Toyan

导航

LeetCode 热题 HOT 100

1. 两数之和

 1 class Solution {
 2     public int[] twoSum(int[] nums, int target) {
 3         Map<Integer, Integer> mapping = new HashMap<>();
 4         for (int i = 0; i < nums.length; i++) {
 5             int key = target - nums[i];
 6             if (mapping.containsKey(key)) {
 7                 return new int[]{mapping.get(key), i};
 8             }
 9             mapping.put(nums[i], i);
10         }
11         return new int[]{-1, -1};
12     }
13 }
View Code

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         ListNode head = new ListNode(-1);
14         ListNode l = head;
15         int sum = 0;
16         boolean carry = false;
17         while (l1 != null || l2 != null) {
18             sum = 0;
19             if (l1 != null) {
20                 sum += l1.val;
21                 l1 = l1.next;
22             }
23             if (l2 != null) {
24                 sum += l2.val;
25                 l2 = l2.next;
26             }
27             if (carry) {
28                 sum++;
29             }
30             l.next = new ListNode(sum % 10);
31             l = l.next;
32             carry = sum / 10 == 0 ? false : true;
33         }
34         if (carry) {
35             l.next = new ListNode(1);
36         }
37         return head.next;
38     }
39 }
View Code

3. 无重复字符的最长子串

 1 class Solution {
 2     public int lengthOfLongestSubstring(String s) {
 3         // 滑动窗口
 4         if (s.length() <= 0) {
 5             return 0;
 6         }
 7         int left = 0;
 8         int max = 0;
 9         Map<Character, Integer> mapping = new HashMap<>();
10         for (int i = 0; i < s.length(); i++) {
11             if (mapping.containsKey(s.charAt(i))) {
12                 left = Math.max(left, mapping.get(s.charAt(i)) + 1);
13             }
14             mapping.put(s.charAt(i), i);
15             max = Math.max(max, i - left + 1);
16         }
17         return max;
18     }
19 }
View Code

76. 最小覆盖子串

很难,看解答理解后敲出来的

 1 class Solution {
 2     public String minWindow(String s, String t) {
 3         if (s == null || s.length() == 0 || t == null || t.length() == 0) {
 4             return "";
 5         }
 6         int[] need = new int[128];
 7         for (int i = 0; i < t.length(); i++) {
 8             need[t.charAt(i)]++;
 9         }
10         int l = 0, r = 0, size = Integer.MAX_VALUE, count = t.length(), start = 0;
11         while (r < s.length()) {
12             char c = s.charAt(r);
13             if (need[c] > 0) {
14                 count--;
15             }
16             need[c]--;
17             if (count == 0) {
18                 while (l < r && need[s.charAt(l)] < 0) {
19                     need[s.charAt(l)]++;
20                     l++;
21                 }
22                 if (r - l + 1 < size) {
23                     size = r - l + 1;
24                     start = l;
25                 }
26                 need[s.charAt(l)]++;
27                 l++;
28                 count++;
29             }
30             r++;
31         }
32         return size == Integer.MAX_VALUE ? "" : s.substring(start, start + size);
33     }
34 }
View Code

30. 串联所有单词的子串

 1 class Solution {
 2     public List<Integer> findSubstring(String s, String[] words) {
 3         List<Integer> res = new ArrayList<>();
 4         if (words == null || words.length == 0) {
 5             return res;
 6         }
 7         Map<String, Integer> allWords = new HashMap<>();
 8         for (String word : words) {
 9             int wordCount = allWords.getOrDefault(word, 0);
10             allWords.put(word, wordCount + 1);
11         }
12         int wordNum = words.length;
13         int wordLen = words[0].length();
14         for (int i = 0; i < s.length() - wordNum * wordLen + 1; i++) {
15             int num = 0;
16             Map<String, Integer> hasWords = new HashMap<>();
17             while (num < wordNum) {
18                 String word = s.substring(i + num * wordLen, i + (num + 1) * wordLen);
19                 if (allWords.containsKey(word)) {
20                     int wordCount = hasWords.getOrDefault(word, 0);
21                     hasWords.put(word, wordCount + 1);
22                     if (hasWords.get(word) > allWords.get(word)) {
23                         break;
24                     }
25                     num++;
26                 } else {
27                     break;
28                 }
29             }
30             if (num == wordNum) {
31                 res.add(i);
32             }
33         }
34         return res;
35     }
36 }
View Code

解法二看答案,思路理解,代码好难、好难

209. 长度最小的子数组

暴力解法

 1 class Solution {
 2     public int minSubArrayLen(int target, int[] nums) {
 3         int min = Integer.MAX_VALUE;
 4         for (int i = 0; i < nums.length; i++) {
 5             int sum = nums[i];
 6             if (sum >= target) {
 7                 return 1;
 8             }
 9             for (int j = i + 1; j < nums.length; j++) {
10                 sum += nums[j];
11                 if (sum >= target) {
12                     min = Math.min(min, j - i + 1);
13                     break;
14                 }
15             }
16         }
17         return min == Integer.MAX_VALUE ? 0 : min;
18     }
19 }
View Code

滑动窗口

 1 class Solution {
 2     public int minSubArrayLen(int target, int[] nums) {
 3         int l = 0, r = 0, sum = 0, min = Integer.MAX_VALUE;
 4         while (r < nums.length) {
 5             sum += nums[r++];
 6             while (sum >= target) {
 7                 min = Math.min(min, r - l);
 8                 sum -= nums[l++];
 9             }
10         }
11         return min == Integer.MAX_VALUE ? 0 : min;
12     }
13 }
View Code
 1 class Solution {
 2     public int minSubArrayLen(int target, int[] nums) {
 3         int l = 0, r = 0, min = Integer.MAX_VALUE;
 4         while (r < nums.length) {
 5             target -= nums[r++];
 6             while (target <= 0) {
 7                 min = Math.min(min, r - l);
 8                 target += nums[l++];
 9             }
10         }
11         return min == Integer.MAX_VALUE ? 0 : min;
12     }
13 }
View Code

窗口大小的方式

 1 class Solution {
 2     public int minSubArrayLen(int target, int[] nums) {
 3         int l = 1, h = nums.length, min = 0;
 4         while (l <= h) {
 5             int mid = (l + h) >> 1;
 6             if (helper(target, nums, mid)) {
 7                 min = mid;
 8                 h = mid - 1;
 9             } else {
10                 l = mid + 1;
11             }
12         }
13         return min;
14     }
15 
16     private boolean helper(int target, int[] nums, int size) {
17         int sum = 0;
18         for (int i = 0; i < nums.length; i++) {
19             if (i >= size) {
20                 sum -= nums[i - size];
21             }
22             sum += nums[i];
23             if (sum >= target) {
24                 return true;
25             }
26         }
27         return false;
28     }
29 }
View Code

4. 寻找两个正序数组的中位数

 1 class Solution {
 2     public double findMedianSortedArrays(int[] nums1, int[] nums2) {
 3         int n = nums1.length;
 4         int m = nums2.length;
 5         // 求中位数的技巧
 6         int left = (n + m + 1) / 2;
 7         int right = (n + m + 2) / 2;
 8         return (findKth(nums1, 0, n - 1, nums2, 0, m - 1, left) + findKth(nums1, 0, n - 1, nums2, 0, m - 1, right)) * 0.5;
 9     }
10 
11     private int findKth(int[] nums1, int start1, int end1, int[] nums2, int start2, int end2, int k) {
12         int len1 = end1 - start1 + 1;
13         int len2 = end2 - start2 + 1;
14         // 保证nums1是短数组
15         if (len1 > len2) {
16             return findKth(nums2, start2, end2, nums1, start1, end1, k);
17         }
18         // nums1已遍历完毕,则一定存在与nums2中,直接返回
19         if (len1 == 0) {
20             return nums2[start2 + k - 1];
21         }
22         // k=1表示两个数组第一个数字,则直接返回最小的即可
23         if (k == 1) {
24             return Math.min(nums1[start1], nums2[start2]);
25         }
26         int i = start1 + Math.min(len1, k / 2) - 1;
27         int j = start2 + Math.min(len2, k / 2) - 1;
28         if (nums1[i] > nums2[j]) {
29             return findKth(nums1, start1, end1, nums2, j + 1, end2, k - Math.min(len2, k / 2));
30         } else {
31             return findKth(nums1, i + 1, end1, nums2, start2, end2, k - Math.min(len1, k / 2));
32         }
33     }
34 }
View Code
 1 class Solution {
 2     public double findMedianSortedArrays(int[] nums1, int[] nums2) {
 3         int len = nums1.length + nums2.length;
 4         if (len % 2 == 0) {
 5             return (findKth(nums1, 0, nums2, 0, len / 2) + findKth(nums1, 0, nums2, 0, len / 2 + 1)) / 2.0;
 6         } else {
 7             return findKth(nums1, 0, nums2, 0, len / 2 + 1);
 8         }
 9     }
10 
11     private int findKth(int[] nums1, int start1, int[] nums2, int start2, int k) {
12         if (start1 >= nums1.length) {
13             return nums2[start2 + k - 1];
14         }
15         if (start2 >= nums2.length) {
16             return nums1[start1 + k - 1];
17         }
18         if (k == 1) {
19             return Math.min(nums1[start1], nums2[start2]);
20         }
21         int i = start1 + k / 2 - 1 < nums1.length ? nums1[start1 + k / 2 - 1] : Integer.MAX_VALUE;
22         int j = start2 + k / 2 - 1 < nums2.length ? nums2[start2 + k / 2 - 1] : Integer.MAX_VALUE;
23         // 一定要是k - k / 2
24         if (i > j) {
25             return findKth(nums1, start1, nums2, start2 + k / 2, k - k / 2);
26         } else {
27             return findKth(nums1, start1 + k / 2, nums2, start2, k - k / 2);
28         }
29     }
30 }
View Code

5. 最长回文子串

暴力法

 1 class Solution {
 2     public String longestPalindrome(String s) {
 3         int len = s.length();
 4         if (len < 2) {
 5             return s;
 6         }
 7         char[] chars = s.toCharArray();
 8         int start = 0;
 9         int maxLen = 1;
10         for (int i = 0; i < len - 1; i++) {
11             for (int j = i + 1; j < len; j++) {
12                 if (j - i + 1 > maxLen && helper(chars, i, j)) {
13                     maxLen = j - i + 1;
14                     start = i;
15                 }
16             }
17         }
18         return s.substring(start, start + maxLen);
19     }
20 
21     private boolean helper(char[] chars, int start, int end) {
22         while (start < end) {
23             if (chars[start] == chars[end]) {
24                 start++;
25                 end--;
26             } else {
27                 return false;
28             }
29         }
30         return true;
31     }
32 }
View Code

动态规划

 1 class Solution {
 2     public String longestPalindrome(String s) {
 3         int len = s.length();
 4         if (len < 2) {
 5             return s;
 6         }
 7         char[] chars = s.toCharArray();
 8         int start = 0;
 9         int maxLen = 1;
10         boolean[][] dp = new boolean[len][len];
11         for (int i = 0; i < len; i++) {
12             dp[i][i] = true;
13         }
14         for (int j = 1; j < len; j++) {
15             for (int i = 0; i < j; i++) {
16                 if (chars[i] != chars[j]) {
17                     dp[i][j] = false;
18                 } else {
19                     if (j - i < 3) {
20                         dp[i][j] = true;
21                     } else {
22                         dp[i][j] = dp[i + 1][j - 1];
23                     }
24                 }
25 
26                 if (j - i + 1 > maxLen && dp[i][j]) {
27                     start = i;
28                     maxLen = j - i + 1;
29                 }
30             }
31         }
32         return s.substring(start, start + maxLen);
33     }
34 }
View Code

10. 正则表达式匹配

 

 

20. 有效的括号

 1 class Solution {
 2     public boolean isValid(String s) {
 3         if (s.isEmpty()) {
 4             return true;
 5         }
 6         if (s.length() % 2 == 1) {
 7             return false;
 8         }
 9         LinkedList<Character> stack = new LinkedList<>();
10         for (char c : s.toCharArray()) {
11             if (c == '(') {
12                 stack.push(')');
13             } else if (c == '{') {
14                 stack.push('}');
15             } else if (c == '[') {
16                 stack.push(']');
17             } else if (stack.isEmpty() || c != stack.pop()) {
18                 return false;
19             }
20         }
21         return stack.isEmpty();
22     }
23 }
View Code

 

posted on 2021-02-23 00:00  Toyan  阅读(81)  评论(0编辑  收藏  举报