class Solution { private int countInRange(int[] nums, int num, int lo, int hi) { int count = 0; for (int i = lo; i <= hi; i++) { if (nums[i] == num) { count++; } } return count; }
private int majorityElementRec(int[] nums, int lo, int hi){ if(lo == hi) return nums[lo];
int mid = (hi-lo)/2 +lo;
int left = majorityElementRec(nums, lo, mid); int right = majorityElementRec(nums, mid+1, hi);
if(left == right){ return left; }
int leftCount = countInRange(nums, left, lo, hi); int rightCount = countInRange(nums, right, lo, hi);
return leftCount>rightCount?left:right; }
public int majorityElement(int[] nums){ return majorityElementRec(nums, 0, nums.length-1); } }
240. 搜索二维矩阵||
编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性:
每行的元素从左到右升序排列。 每列的元素从上到下升序排列。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
class Solution { public boolean searchMatrix(int[][] matrix, int target) { int m = matrix.length, n = matrix[0].length;
int x = 0, y = n-1; while(x<m&&y>=0){ if(matrix[x][y]==target) return true; if(matrix[x][y]>target){ --y; }else{ ++x; } } return false; } }
class Solution { public int findCircleNum(int[][] isConnected) { int[] parent = new int[isConnected.length];
int n = isConnected.length; for(int i=0;i<n;i++){ parent[i] = i; }
for(int i =0;i<n;i++){ for(int j = i+1;j<n;j++){ if(isConnected[i][j]==1){ union(parent, i, j); } } } int pro = 0; for(int i =0;i<n;i++){ if(parent[i]==i){ pro++; } }
return pro; }
public void union(int[] parent, int index1, int index2){ parent[find(parent, index1)] = find(parent, index2); }
public int find(int[] parent, int index){ if(parent[index]!=index){ parent[index] = find(parent, parent[index]); }
class Solution { public int findCircleNum(int[][] isConnected) { int pro = 0; int n = isConnected.length; boolean[] visited = new boolean[n];
for(int i = 0;i<n;i++){ if(!visited[i]){ dfs(isConnected, visited, n, i); pro++; } }
return pro; }
public void dfs(int[][] isConnected, boolean[] visited, int n, int i){ for(int j=0;j<n;j++){ if(isConnected[i][j]==1 && !visited[j]){ visited[j]=true; dfs(isConnected, visited, n, j); } } } }
class Solution { public int[] findRedundantConnection(int[][] edges) { int n = edges.length; int[] parent = new int[n+1]; for(int i=1;i<=n;i++){ parent[i]=i; }
class Solution { public int minSubArrayLen(int target, int[] nums) { int n = nums.length; int length = Integer.MAX_VALUE; int sum = 0; int end = 0, start = 0; while(end<n){ sum += nums[end]; while(sum>=target){ length = Math.min(length, end-start+1); sum -= nums[start]; start++; } end++; }
return length == Integer.MAX_VALUE?0:length; } }
3. 无重复字符的最长子串
给定一个字符串 s ,请你找出其中不含有重复字符的 最长 子串的长度。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
class Solution { public int lengthOfLongestSubstring(String s) { char[] ch = s.toCharArray(); int n = s.length(); int res = 0; for(int i =0;i<n;i++){ Set<Character> hset = new HashSet<>(); int j = i+1; hset.add(ch[i]); while(j<n&&!hset.contains(ch[j])){ hset.add(ch[j]); j++; } res = Math.max(res, hset.size()); }
class Solution { public int longestOnes(int[] nums, int k) { int n = nums.length; int res = 0; int count = 0; int left = 0; int right = 0; while(right<n){ if(nums[right]==0) count++; right++; while(count>k){ if(nums[left]==0) count--; left++; } res = Math.max(res,right-left); }
return res; } }
1208. 尽可能使字符串相等
给你两个长度相同的字符串,s 和 t。
将 s 中的第 i 个字符变到 t 中的第 i 个字符需要 |s[i] - t[i]| 的开销(开销可能为 0),也就是两个字符的 ASCII 码值的差的绝对值。
class Solution { public int equalSubstring(String s, String t, int maxCost) { int n = s.length(); int res = 0; int left = 0; int right = 0; int sum = 0; int[] diff = new int[n]; for(int i=0;i<n;i++){ diff[i] = Math.abs(s.charAt(i)-t.charAt(i)); }
while(right<n){ sum += diff[right]; right++; while(sum>maxCost){ sum -= diff[left]; left++; } res = Math.max(res, right-left); }
class Solution { public int pivotIndex(int[] nums) { int n = nums.length; int[] pre = new int[n]; int[] after = new int[n]; pre[0] = nums[0]; after[n-1] = nums[n-1]; for(int i =1;i<n;i++){ pre[i] += pre[i-1] + nums[i]; } for(int i = n-2;i>=0;i--){ after[i] += after[i+1] + nums[i]; }
for(int i = 0;i<n;i++){ if(pre[i]-nums[i] == after[i]-nums[i]) return i; }
return -1; } }
560. 和为k的子数组
给你一个整数数组 nums 和一个整数 k ,请你统计并返回 该数组中和为 k 的子数组的个数 。
子数组是数组中元素的连续非空序列。
暴力
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
public class Solution { public int subarraySum(int[] nums, int k) { int count = 0; for (int start = 0; start < nums.length; ++start) { int sum = 0; for (int end = start; end >= 0; --end) { sum += nums[end]; if (sum == k) { count++; } } } return count; } }
前缀和+哈希表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
class Solution { public int subarraySum(int[] nums, int k) { int n = nums.length; int count = 0, pre = 0; Map<Integer, Integer> map = new HashMap<>(); map.put(0, 1); for(int i=0;i<n;i++){ pre += nums[i]; if(map.containsKey(pre-k)){ count += map.get(pre-k); } map.put(pre, map.getOrDefault(pre, 0)+1); }