704 二分查找 左闭右开
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 class Solution { public int search (int [] nums, int target) { if (target < nums[0 ] || target > nums[nums.length - 1 ]) return -1 ; int left = 0 ; int right = nums.length; while (left < right){ int mid = left + ((right - left) >> 1 ); if (nums[mid] == target){ return mid; } else if (nums[mid] > target){ right = mid; } else { left = mid + 1 ; } } return -1 ; } }
左闭右闭
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 class Solution { public int search (int [] nums, int target) { if (target < nums[0 ] || target > nums[nums.length - 1 ]){ return -1 ; } int left = 0 ; int right = nums.length - 1 ; while (left <= right){ int mid = left + ((right - left) >> 1 ); if (nums[mid] == target){ return mid; } else if (target < nums[mid]){ right = mid - 1 ; } else { left = mid + 1 ; } } return -1 ; } }
35 搜索插入位置 二分查找,输出mid或左值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 class Solution { public int searchInsert (int [] nums, int target) { if (target < nums[0 ]) return 0 ; if (target > nums[nums.length - 1 ]) return nums.length; int left = 0 ; int right = nums.length; while (left < right){ int mid = left + ((right - left) >> 1 ); if (nums[mid] == target) { return mid; } else if (target > nums[mid]){ left = mid + 1 ; } else { right = mid; } } return left; } }
34 在排序数组中查找元素的第一个和最后一个位置 在数组中找到位置,然后滑动左右指针找到
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 class Solution { public int [] searchRange(int [] nums, int target) { if (nums.length == 0 ) return new int [] {-1 , -1 }; int index = binarySearch(nums, target); if (index == -1 ) return new int [] {-1 , -1 }; else { int left = index; int right = index; for (int i = index; i >= 0 ; i--){ if (nums[i] == target) left--; } for (int i = index; i < nums.length; i++){ if (nums[i] == target) right++; } return new int [] {left + 1 , right - 1 }; } } private int binarySearch (int [] nums, int target) { if (target < nums[0 ] || target > nums[nums.length - 1 ]) return -1 ; int left = 0 ; int right = nums.length; while (left < right){ int mid = left + ((right - left) >> 1 ); if (nums[mid] == target){ return mid; } else if (target > nums[mid]){ left = mid + 1 ; } else { right = mid; } } return -1 ; } }
在二分查找之中找到左边界和右边界
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 class Solution { public int [] searchRange(int [] nums, int target) { return new int [] {getLeftBorder(nums, target), getRightBorder(nums, target)}; } private int getLeftBorder (int [] nums, int target) { if (nums.length == 0 || target < nums[0 ] || target > nums[nums.length - 1 ]) return -1 ; int left = 0 ; int right = nums.length; while (left < right){ int mid = left + ((right - left) >> 1 ); if (nums[mid] == target){ for (int i = mid; i >= left; i--){ if (nums[mid] == target) mid--; } return mid + 1 ; } else if (target > nums[mid]){ left = mid + 1 ; } else { right = mid; } } return -1 ; } private int getRightBorder (int [] nums, int target) { if (nums.length == 0 || target < nums[0 ] || target > nums[nums.length - 1 ]) return -1 ; int left = 0 ; int right = nums.length; while (left < right){ int mid = left + ((right - left) >> 1 ); if (nums[mid] == target){ for (int i = mid; i < right; i++){ if (nums[mid] == target) mid++; } return mid - 1 ; } else if (target > nums[mid]){ left = mid + 1 ; } else { right = mid; } } return -1 ; } }
69 x的平方根 注意返回的数字 是 右 - 1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 class Solution { public int mySqrt (int x) { if (x == 0 ) return 0 ; if (x == 1 ) return 1 ; int left = 0 ; int right = x; while (left < right){ int mid = left + ((right - left) >> 1 ); long midSquare = (long ) mid * mid; if (midSquare == (long ) x){ return mid; } else if (midSquare < x){ left = mid + 1 ; } else { right = mid; } } return right - 1 ; } }
367 有效的完全平方数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 class Solution { public boolean isPerfectSquare(int num) { if (num == 0 || num == 1) return true; int left = 0; int right = num; while (left < right){ int mid = left + ((right - left) >> 1); long midS = (long) mid * mid; if (midS == (long) num) { return true; } else if (midS < num){ left = mid + 1; } else { right = mid; } } return false; } }
27 移除元素 快慢指针
1 2 3 4 5 6 7 8 9 10 11 12 13 class Solution { public int removeElement (int [] nums, int val) { int slowIndex = 0 ; for (int fastIndex = 0 ; fastIndex < nums.length; fastIndex++){ if (nums[fastIndex] != val){ nums[slowIndex++] = nums[fastIndex]; } } return slowIndex; } }
左右指针
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 class Solution { public int removeElement (int [] nums, int val) { int left = 0 ; int right = nums.length - 1 ; for (left = 0 ; left <= right; left++){ if (nums[left] == val){ nums[left] = nums[right--]; left--; } } return left; } }
26 删除排序数组中的重复项 快慢指针
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 class Solution { public int removeDuplicates (int [] nums) { int fastIndex = 0 ; int slowIndex = 1 ; for (fastIndex = 1 ; fastIndex< nums.length; fastIndex++){ if (nums[fastIndex] != nums[slowIndex - 1 ]){ nums[slowIndex] = nums[fastIndex]; slowIndex++; } } return slowIndex; } }
283 移动零 快慢指针的另种用法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class Solution { public void moveZeroes (int [] nums) { int fastIndex = 0 ; int slowIndex = 0 ; for (fastIndex = 0 ; fastIndex < nums.length; fastIndex++){ if (nums[fastIndex] != 0 ){ nums[slowIndex++] = nums[fastIndex]; } } for (int i = slowIndex; i < nums.length; i++){ nums[i] = 0 ; } } }
844 比较含退格的字符串 利用stringbuilder
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 class Solution { public boolean backspaceCompare (String s, String t) { s = getString(s); t = getString(t); return s.equals(t); } private String getString (String s) { StringBuilder sb = new StringBuilder (); char [] chars = s.toCharArray(); for (char i : chars){ if (i == '#' ){ if (sb.length() != 0 ){ sb.delete(sb.length() - 1 , sb.length()); } } else { sb.append(i); } } return sb.toString(); } }
977 有序数组的平方 左右指针
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 class Solution { public int [] sortedSquares(int [] nums) { int [] result = new int [nums.length]; int left = 0 ; int right = nums.length - 1 ; int index = nums.length - 1 ; while (left <= right){ int leftS = nums[left] * nums[left]; int rightS = nums[right] * nums[right]; if (leftS <= rightS) { result[index--] = rightS; right--; } else { result[index--] = leftS; left++; } } return result; } }
209 长度最小的子数组 滑动窗口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 class Solution { public int minSubArrayLen (int target, int [] nums) { int left = 0 ; int right = 0 ; int sum = 0 ; int result = Integer.MAX_VALUE; for (right = 0 ; right < nums.length; right++){ sum += nums[right]; while (sum >= target){ result = Math.min(result, right - left + 1 ); sum -= nums[left++]; } } return result == Integer.MAX_VALUE ? 0 : result; } }
904 水果成篮 利用HashMap计数,然后在hashmap里面为0时删除 记录length 比较最长
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 class Solution { public int totalFruit (int [] fruits) { int result = 0 ; Map<Integer, Integer> map = new HashMap <>(); int left = 0 ; int right = 0 ; for (right = 0 ; right < fruits.length; right++) { map.put(fruits[right], map.getOrDefault(fruits[right],0 ) + 1 ); while (map.size() > 2 ){ map.put(fruits[left], map.get(fruits[left]) - 1 ); if (map.get(fruits[left]) == 0 ) map.remove(fruits[left]); left++; } result = Math.max(result, right - left + 1 ); } return result; } }
76 最小覆盖子串 利用两个hashmap记录次数,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 class Solution { public String minWindow (String s, String t) { Map<Character, Integer> need = new HashMap <>(); Map<Character, Integer> window = new HashMap <>(); for (char i : t.toCharArray()){ need.put(i, need.getOrDefault(i, 0 ) + 1 ); } int left = 0 , right = 0 ; int valid = 0 ; int start = 0 , len = Integer.MAX_VALUE; while (right < s.length()){ char c = s.charAt(right); right++; if (need.containsKey(c)){ window.put(c, window.getOrDefault(c, 0 ) + 1 ); if (window.get(c).equals(need.get(c))){ valid++; } } while (valid == need.size()){ if (right - left < len){ start = left; len = right - left; } char d = s.charAt(left); left++; if (need.containsKey(d)){ if (window.get(d).equals(need.get(d))){ valid--; } window.put(d, window.get(d) - 1 ); } } } return len == Integer.MAX_VALUE ? "" : s.substring(start, start + len); } }
59 螺旋矩阵II 模拟过程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 class Solution { public int [][] generateMatrix(int n) { int [][] result = new int [n][n]; int start = 0 ; int count = 1 ; int offset = 1 ; int loop = n / 2 ; int i = 0 , j = 0 ; while (loop-- > 0 ){ for (j = start; j < n - offset; j++){ result[start][j] = count++; } for (i = start; i < n - offset; i++){ result[i][j] = count++; } for (;j > start; j--){ result[i][j] = count++; } for (;i > start; i--){ result[i][j] = count++; } start++; offset++; } if (n % 2 == 1 ){ result[start][start] = count; } return result; } }
54 螺旋数组 此时由于数组不规则,不适用规则上面的规则
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 class Solution { public List<Integer> spiralOrder (int [][] matrix) { List<Integer> list = new ArrayList (); int m = matrix.length, n = matrix[0 ].length; int rowSt = 0 , colSt = 0 , rowEnd = m - 1 , colEnd = n - 1 ; while (list.size() < m * n){ for (int i = colSt; i <= colEnd; i++){ list.add(matrix[rowSt][i]); } for (int i = rowSt + 1 ; i <= rowEnd; i++){ list.add(matrix[i][colEnd]); } if (rowSt != rowEnd){ for (int i = colEnd - 1 ; i >= colSt; i--){ list.add(matrix[rowEnd][i]); } } if (colSt != colEnd){ for (int i = rowEnd - 1 ; i >= rowSt + 1 ; i--){ list.add(matrix[i][colSt]); } } colSt++; colEnd--; rowSt++; rowEnd--; } return list; } }