LeetCode 2.Add Two Numbers & 3.Longest Substring Without Repeating Characters


Problem 2 :Add Two Numbers

You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list.
You may assume the two numbers do not contain any leading zero, except the number 0 itself.
Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)
Output: 7 -> 0 -> 8



解题思路:

1. 主要考虑进位问题,满十往前进一位

2. 循环计算每一位上的结果,就是两个数的对应位相加再加上进位,直到两个数都到达空节点后跳出循环

3. 考虑两个数长度不一样的情况,即一方ListNode为空时,不能继续往后遍历,要全用0代替

4. 考虑最后的边界情况,两个N位整数相加,最高位正好进位,结果变为N+1位整数

5. Java对象和引用的问题需要注意。

代码如下:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
public class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
       ListNode mark = new ListNode(0);
       ListNode result = mark;
       int flag = 0;

        while(l1 != null || l2 != null){
          ListNode current = new ListNode(0);
          int v,v1,v2;
          if(l1 == null){v1 = 0;}
          else{v1 = l1.val;}
          if(l2 == null){v2 = 0;}
          else{v2 = l2.val;}

            v = v1 + v2 + flag;
            if(v >= 10){
              current.val = v % 10;
              flag = 1;
            }
            else{
              current.val = v;
              flag = 0;
            }

            if(l1!= null) l1 = l1.next;
            if(l2!=null) l2 = l2.next;
            
           
            mark.next = current;
            mark = current;           
        }
        if(flag == 1){
          ListNode current = new ListNode(1);
          mark.next = current;
        }
        

      return result.next;        
    }
}


Problem 3:Longest Substring Without Repeating Characters

Given a string, find the length of the longest substring without repeating characters.
Examples:
Given "abcabcbb", the answer is "abc", which the length is 3.
Given "bbbbb", the answer is "b", with the length of 1.
Given "pwwkew", the answer is "wke", with the length of 3. Note that the answer must be a substring, "pwke" is a subsequence and not a substring.


解题思路:

1. 寻找不重复的子串,第一想法就是利用HashSet,因为HashSet里不允许有重复元素

2. 从头开始遍历字符串的每一个字符,再内嵌一个循环向后寻找以该字符开始的子串,用HashSet保存,直到出现重复的字符,子串寻找结束,将得到的子串的长度(HashSet的大小)与记录的最大值进行比较,保留较大的值,然后跳出循环,重新开始寻找由下一字符开始的子串

3. 子串每进行一次更新,都需要update一次最大值

代码如下:

public class Solution {
    public int lengthOfLongestSubstring(String s) {
        int length = s.length();
        if(length == 0) {
        return 0;
      }
        int max = 1;
        
        for(int i = 0;i < length;i++){
          Set<Character> charSet = new HashSet<Character>();
          charSet.add(s.charAt(i));

          for(int j = i+1;j < length;j++){
            if(charSet.contains(s.charAt(j))){
              max = (max < charSet.size()) ? charSet.size() : max;
              break;
            }
            else{
              charSet.add(s.charAt(j));
              max = (max < charSet.size()) ? charSet.size() : max;
              
            }

          }
        }
        return max;
    }
}


不过需要注意的是,虽然算法没有问题,但是由于遍历了字符串所有的不包含重复字符的子串,所以非常耗时,最后代码的结果虽然通过了所有的测试用例,但是超时了,并不能通过。


所以下面分享在其他用户评论中看到的另一种利用HashSet的更加简单的思路:

1. 因为只需要记录最大的不包含重复字符的子串的长度,所以并不需要遍历所有的不包含重复字符的子串,因为一个长的子串中,可能包含了很多的短子串,如"abcdeeee",按照第一种方法,则遍历了子串"abcde"、"bcde"、"cde"、"de"、"e",遍历"abcde"一次之后,已经得到了一个最大值,之后在再遍历的四次,都是它的子串,是多余的步骤,这样的额步骤一多,就变得非常耗时

2. 因此可以考虑用两个“指针”来分别代表子串的头和尾,两指针中间的部分则代表子串,尾指针从字符转的第一个字符开始向后遍历,直到遍历到与之前有重复的字符,记录子串长度,然后开始从第一个字符开始向后移动头指针,直到两指针中间的子串不再包含相同字符后,头指针停下,尾指针继续向后移动,如此反复。在这种方法下,对字符串"abcdeeee"进行操作,只需要遍历子串"abcde"和"e",直接跳过了较短的子串(子串的子串),大大节省了时间。

代码如下:

public int lengthOfLongestSubstring(String s) {
    int i = 0, j = 0, max = 0;
    Set<Character> set = new HashSet<>();
    
    while (j < s.length()) {
        if (!set.contains(s.charAt(j))) {
            set.add(s.charAt(j++));
            max = Math.max(max, set.size());
        } else {
            set.remove(s.charAt(i++));
        }
    }
    
    return max;
}


看了别人的代码之后,才深刻觉得自己的做法有多么繁琐,很多时候我们不能光想着怎么解决问题就行,还要想着如何把问题解决的更快更好。希望以后可以坚持练习,努力提高自己的代码水平吧。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值