流下了不学无术的泪水:今天你刷题了吗(二)

点击上方“程序人生”,选择“置顶公众号”

第一时间关注程序猿(媛)身边的故事


《今天你刷题了吗(?)》是小班克发起的一场做算法题的活动,该活动会尽量保持在一周一期,喜欢刷题的、或者对刷题有需要的同僚,可以跟着小班克我一起,每周一道算法题。当然,能力较强或者时间较多的朋友也可以自己去LeetCode上注册一个账号,按照自己的速度刷题。那么闲话不多说,我们一起来看看上期留下的问题的解决方案吧!


题目如下:



翻译过来就是:给出两个表示非负整数的数字链表,数字以相反的顺序存储,每个链表都存储该非负整数某一位上的数字。计算两个非负整数的和,并以链表的方式返回。简单做个比喻:342,以链表的存储形式就是,2->4->3

 

解题过程:


解题思路如下:这道题在LeetCode上的难度是中等难度(在LeetCode上题目的难度只有简单、中等、困难。第一期的题目是简单)。但是我觉得这题要比上一题更加简单。我们只要将对应的位数相加即可,唯一麻烦一点的地方就是判断何时结束计算。小班克我在做这一题的时候,用了一个递归的方法,因为可以很简单的看出,其实每一位相加的规则都是一样的(满十进一之类的)。需要注意的是,递归之后返回的链表节点其实是表尾,那么我们直接来看代码吧。


/**
* Definition for singly-linked list.
* public class ListNode {
*     public int val;
*     public ListNode next;
*     public ListNode(int x) { val = x; }
* }
*/

public class Solution {
  public ListNode AddTwoNumbers(ListNode l1, ListNode l2)
       
{
           AddTwoNumbersRecursion(l1, l2);

           return l1;
       }

       public void AddTwoNumbersRecursion(ListNode l1, ListNode l2)
       
{
           l1.val += l2.val;

           if (l1.val >= 10)
           {
               if (l1.next == null)
                   l1.next = new ListNode(0);

               l1.next.val += 1;
               l1.val %= 10;
           }

           if (l1.next == null && l2.next == null)
               return;
           else if (l1.next == null && l2.next != null)
               l1.next = new ListNode(0);
           else if(l1.next != null && l2.next == null)
               l2.next = new ListNode(0);

           AddTwoNumbersRecursion(l1.next, l2.next);
       }
}


时间复杂度:O(n)。为什么是O(n)呢?自己去上一期补课去!(详情请见第一期的斐波那契数列

空间复杂度:O(n)

 

这个解题方案小班克我自己还是很满意的,我也是在写完第一期的内容之后,受到斐波那契数列的启发,写出了这题答案,数据说明了一切(也可能是大家都觉得这题太简单,懒得去想更快的解题方案吧)。



public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
   ListNode dummyHead = new ListNode(0);
   ListNode p = l1, q = l2, curr = dummyHead;
   int carry = 0;
   while (p != null || q != null) {
       int x = (p != null) ? p.val : 0;
       int y = (q != null) ? q.val : 0;
       int sum = carry + x + y;
       carry = sum / 10;
       curr.next = new ListNode(sum % 10);
       curr = curr.next;
       if (p != null) p = p.next;
       if (q != null) q = q.next;
   }
   if (carry > 0) {
       curr.next = new ListNode(carry);
   }
   return dummyHead.next;
}


解题思路:官方使用了一个 While 循环,当 p 和 q 都为空时,跳出循环。具体代码小班克觉得没什么可以细说的(有什么看不懂的可以给编辑大大留言,我相信编辑大大会给你们一个满意的答复的。手动滑稽= =)。


时间复杂度:O(Max(m, n))。这个 While 循环是当 p 和 q 都为空时,才会终止,因此,循环会执行 Max(p 的长度,q 的长度) 次。


空间复杂度:O(Max(m, n))。从程序中,我们可以看到每一次的 While 循环,都会重新创建 x、y、sum 三个临时变量,因此空间复杂度为 O(Max(p 的长度,q 的长度))。


下期题目:


那我们接下来就来看看下一期的题目,这一题的难度是中等难度:



翻译过来就是:给你一个字符串,找出最长的没有重复字符的子字符串的长度。


我相信大家不会都只能像小班克一样用穷举法做吧,干巴爹~


点击图片get往期内容

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值