首页 > 其他 > 详细

力扣 #1两数之和 #2两数相加 #3无重复字符的最长子串

时间:2020-12-05 22:35:16      阅读:39      评论:0      收藏:0      [点我收藏+]

最近两天的日常题也太难了罢 今天的抄个答案放弃了 索性从头开始复习一下1 ~ 300题好了 本人末流211本科 不想考研 大一大二学习不是很用功 现在在努力追进度 脑子不好使 大家轻喷

class Solution {
    public int[] twoSum(int[] nums, int target) {
        int n = nums.length;
        for (int i = 0; i < n; ++i) {
            for (int j = i + 1; j < n; ++j) {
                if (nums[i] + nums[j] == target) {
                    return new int[]{i, j};
                }
            }
        }
        return new int[0];
    }
}

方法一 两次循环 时间复杂度O(N)

class Solution {
    public int[] twoSum(int[] nums, int target) {
        HashMap<Integer,Integer> map = new HashMap<>();
        for(int i = 0; i < nums.length; i++){
            map.put(nums[i],i);
        }
        for(int j = 0; j < nums.length; j++){
            if(map.containsKey(target - nums[j])&&map.get(target - nums[j])!= j){
                return new int[]{j, map.get(target - nums[j])};
            }
        }
        return null;
    }
}

#1注意特殊情况 比如 [2,3] 目标是4 要避免2重复取到的情况

 1 /**
 2  * Definition for singly-linked list.
 3  * public class ListNode {
 4  *     int val;
 5  *     ListNode next;
 6  *     ListNode() {}
 7  *     ListNode(int val) { this.val = val; }
 8  *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 9  * }
10  */
11 class Solution {
12     public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
13         int carry = 0;
14         int sum = 0;
15         ListNode res = new ListNode(0);
16         ListNode ans = res;
17         while(l1 != null || l2 != null){
18             int left = l1 == null?0:l1.val;
19             int right = l2 == null?0:l2.val;
20             sum = carry + left + right;
21             res.next = new ListNode(sum%10);
22             carry = sum/10;
23             sum = sum%10;
24             res = res.next;
25             if(l1 != null) l1 = l1.next;
26             if(l2 != null) l2 = l2.next;
27         }
28         if(carry > 0){
29             res.next = new ListNode(1);
30         }
31         return ans.next;
32     }
33 }

#2设置一个进位标志carry 两数相加和为(0, 18)之间 我们新节点的值容易理解是 % 10剩下的那个数 加上上一位的进位标志(如果上一位有进位的话)

然后如果有进位(两数之和大于10)进位也就是 /10 最多为1嘛 最后两个链表走完了判断一下最外面有没有进位 也就是类似 3 + 7 = 10的情况

然后要注意的也就是链表的转移了 等过两天链表感觉有点忘了也许会整理一下链表的题目罢

 1 class Solution {
 2     public int lengthOfLongestSubstring(String s) {
 3         char[] str = s.toCharArray();
 4         int res = 0;
 5         for(int i = 0; i < str.length; i++){
 6             HashSet<Character> set = new HashSet<>();
 7             int count = 0;
 8             for(int j = i; j < str.length; j++){
 9                 if(!set.contains(str[j])){
10                     count++;
11                     set.add(str[j]);
12                 }else{
13                     count = 0;
14                 }
15                 res = Math.max(res, count);
16             }
17         }
18         return res;
19     }
20 }

#3 好久之后第二次写 无脑暴力 思路没问题......但是超时了  986 / 987 个通过测试用例 时间复杂度在O(N)和O(N^2)之间吧 空间复杂度O(N) 不是很会算唉

 1 class Solution {
 2     public int lengthOfLongestSubstring(String s) {
 3         HashSet<Character> set = new HashSet<>();
 4         int len = s.length();
 5         int res = 0, left = 0, right = 0;
 6         while(left < len && right < len){
 7             if(!set.contains(s.charAt(right))){
 8                 set.add(s.charAt(right++));
 9                 res = Math.max(res, (right - left));
10             }else{
11                 set.remove(s.charAt(left++));
12             }
13         }
14         return res;
15     }
16 }

第二种方法 滑动窗口 很巧妙的地方是 用到的是 i++ 而不是 ++i 时间复杂度O(2N) === O(N)

a b c a b c a

i      j

a b c a b c a

i        j

a b c a b c a 这边是先remove了 s.charAt(left++) (为第一个a) 然后又判断了一次 把第二个a add到了set 中

   i        j

a b c a b c a

      i        j

 1 class Solution {
 2     public int lengthOfLongestSubstring(String s) {
 3         int len = s.length(), res = 0;
 4         HashMap<Character, Integer> map = new HashMap<>();
 5         for(int i = 0, j = 0; j < len; j++){
 6             if(map.containsKey(s.charAt(j))){
 7                 i = Math.max(map.get(s.charAt(j)),i);
 8             }
 9             map.put(s.charAt(j), j + 1); //j + 1表示 i要移动的下一个位置 
10             res = Math.max(res, j + 1 - i);
11         }
12         return res;
13     }
14 }

方法二 优化

a b c d c c a

a b c d c c a

a b c d c c a这种情况下我们会做无用的移除 可以一步到位跳跃到下一个c的位置 时间复杂度O(N)

a b c d c c a

由于map中的 i 之前的位置没有 remove 所以我们要Math.max ( map.get ( s.charAt ( j ) ) , i ) 确认 i 的坐标不是之前出现的

 

力扣 #1两数之和 #2两数相加 #3无重复字符的最长子串

原文:https://www.cnblogs.com/doomslayer/p/14090746.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!