• LeetCode: 2. 两数相加


    2. 两数相加

    难度中等8421

    给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。

    请你将两个数相加,并以相同形式返回一个表示和的链表。

    你可以假设除了数字 0 之外,这两个数都不会以 0 开头。

    示例 1:

    输入:l1 = [2,4,3], l2 = [5,6,4]
    输出:[7,0,8]
    解释:342 + 465 = 807.
    

    示例 2:

    输入:l1 = [0], l2 = [0]
    输出:[0]
    

    示例 3:

    输入:l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9]
    输出:[8,9,9,9,0,0,0,1]
    

    提示:

    • 每个链表中的节点数在范围 [1, 100] 内
    • 0 <= Node.val <= 9
    • 题目数据保证列表表示的数字不含前导零

    思路:利用字符串按位相加,注意考虑进位及新链表的节点的处理。具体见代码注释~

    1. 整体思路优化精简前,
    2. 整体思路优化精简ing...
    3. 整体思路优化精简后。

    时间复杂度:O(max(m,n)),其中 m 和 n 分别为两个链表的长度。我们要遍历两个链表的全部位置,而处理每个位置只需要 O(1) 的时间。

    空间复杂度: O(1),注意返回值不计入空间复杂度。

    1. /**
    2. * Definition for singly-linked list.
    3. * type ListNode struct {
    4. * Val int
    5. * Next *ListNode
    6. * }
    7. */
    8. // 1、整体思路优化精简前:
    9. // func addTwoNumbers(l1 *ListNode, l2 *ListNode) *ListNode {
    10. // head := &ListNode{}
    11. // carry := 0 // 进位值,一般为1
    12. // cur, cur1, cur2 := head, l1, l2
    13. // for cur1 != nil || cur2 != nil { // 注意:条件为 ||
    14. // sum := 0
    15. // if cur1 != nil && cur2 != nil {
    16. // sum = cur1.Val + cur2.Val + carry
    17. // cur.Next = &ListNode{
    18. // Val: sum%10, // 取模 + 上一轮进位
    19. // Next:nil,
    20. // }
    21. // cur, cur1, cur2 = cur.Next, cur1.Next, cur2.Next
    22. // } else if cur1 != nil {
    23. // sum = cur1.Val + carry
    24. // cur.Next = &ListNode{
    25. // Val: sum%10, // 取模 + 上一轮进位
    26. // Next:nil,
    27. // }
    28. // cur, cur1 = cur.Next, cur1.Next
    29. // } else if cur2 != nil {
    30. // sum = cur2.Val + carry
    31. // cur.Next = &ListNode{
    32. // Val: sum%10, // 取模 + 上一轮进位
    33. // Next:nil,
    34. // }
    35. // cur, cur2 = cur.Next, cur2.Next
    36. // }
    37. // // 单独处理下一轮的进位
    38. // if sum >= 10 {
    39. // carry = 1
    40. // } else {
    41. // carry = 0
    42. // }
    43. // }
    44. // // 当l1和l2都遍历完后,处理最后的一次进位。例如:99+9=108,这里需要处理百位最后的1
    45. // if carry != 0 {
    46. // cur.Next = &ListNode{
    47. // Val: carry,
    48. // Next: nil,
    49. // }
    50. // }
    51. // return head.Next
    52. // }
    53. // 2、整体思路优化精简ing:
    54. // func addTwoNumbers(l1 *ListNode, l2 *ListNode) *ListNode {
    55. // head := &ListNode{}
    56. // carry := 0 // 进位值,一般为1
    57. // cur, cur1, cur2 := head, l1, l2
    58. // for cur1 != nil || cur2 != nil { // 注意:条件为 ||
    59. // sum := 0
    60. // if cur1 != nil && cur2 != nil {
    61. // sum = cur1.Val + cur2.Val + carry
    62. // cur1, cur2 = cur1.Next, cur2.Next
    63. // } else if cur1 != nil {
    64. // sum = cur1.Val + carry
    65. // cur1 = cur1.Next
    66. // } else if cur2 != nil {
    67. // sum = cur2.Val + carry
    68. // cur2 = cur2.Next
    69. // }
    70. // // 单独处理新链表的节点
    71. // cur.Next = &ListNode{
    72. // Val: sum%10, // 取模 + 上一轮进位
    73. // Next:nil,
    74. // }
    75. // cur = cur.Next
    76. // // 单独处理下一轮的进位
    77. // if sum >= 10 {
    78. // carry = 1
    79. // } else {
    80. // carry = 0
    81. // }
    82. // }
    83. // // 当l1和l2都遍历完后,处理最后的一次进位。例如:99+9=108,这里需要单独处理百位最后的1
    84. // if carry != 0 {
    85. // cur.Next = &ListNode{
    86. // Val: carry,
    87. // Next: nil,
    88. // }
    89. // }
    90. // return head.Next
    91. // }
    92. // 3、整体思路优化精简后:
    93. func addTwoNumbers(l1 *ListNode, l2 *ListNode) *ListNode {
    94. head := &ListNode{}
    95. cur := head
    96. carry := 0 // 进位值,一般为1
    97. for l1 != nil || l2 != nil { // 注意:条件为 ||
    98. sum, val1, val2 := 0, 0, 0
    99. if l1 != nil {
    100. val1 = l1.Val
    101. l1 = l1.Next
    102. }
    103. if l2 != nil {
    104. val2 = l2.Val
    105. l2 = l2.Next
    106. }
    107. sum = val1 + val2 + carry
    108. sum, carry = sum%10, sum/10 // 单独处理下一轮的carry进位
    109. // 单独处理新链表的节点
    110. cur.Next = &ListNode{
    111. Val: sum,
    112. Next:nil,
    113. }
    114. cur = cur.Next
    115. }
    116. // 当l1和l2都遍历完后,处理最后的一次进位。例如:99+9=108,这里需要单独处理百位最后的1
    117. if carry != 0 {
    118. cur.Next = &ListNode{
    119. Val: carry,
    120. Next: nil,
    121. }
    122. }
    123. return head.Next
    124. }

  • 相关阅读:
    leetcode 654 最大二叉树
    苹果所有设备参数大全
    FreeRTOS个人笔记-支持时间片
    服务网络基础
    dragonfly数据库
    浏览器、负载均衡 、进程内部层…那些你需要掌握的多级缓存
    LuatOS-SOC接口文档(air780E)-- i2s - 数字音频
    .net餐厅管理系统数据层餐厅服务类添加订单、添加、删除收藏信息
    如何使用idea快速克隆web项目,并且使其能访问jsp页面
    日期类的实现
  • 原文地址:https://blog.csdn.net/qq_37102984/article/details/126104262