Tag题选编 2115. Find All Possible Recipes from Given Supplies 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 public List<String> findAllRecipes (String[] recipes, List<List<String>> ingredients, String[] supplies) { Set<String> res=new HashSet <>(); int n=recipes.length; Map<String, Set<String>> map=new HashMap <>(); for (int i = 0 ; i < n; i++) { map.put(recipes[i],new HashSet <>()); for (String s : ingredients.get(i)) { map.get(recipes[i]).add(s); } } Deque<String> q=new LinkedList <>(); for (String supply : supplies) { q.offer(supply); } while (!q.isEmpty()){ String s=q.poll(); for (String r : map.keySet()) { if (map.get(r).contains(s)){ map.get(r).remove(s); if (map.get(r).size()==0 ){ res.add(r); q.offer(r); } } } } return new ArrayList <>(res); }
1048. Longest String Chain 思路:
Instead of adding a character, try deleting a character to form a chain in reverse.
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 public int longestStrChain (String[] words) { Map<String,Integer> map=new HashMap <>(); int n=words.length; for (int i = 0 ; i < n; i++) { map.put(words[i],i); } boolean [] visited=new boolean [n]; PriorityQueue<int []> q=new PriorityQueue <>((a,b)->(b[1 ]!=a[1 ] ? b[1 ]-a[1 ] : words[b[0 ]].length()-words[a[0 ]].length())); for (int i = 0 ; i < n; i++) { q.offer(new int []{i,1 }); } int res=0 ; while (!q.isEmpty()){ int [] cur=q.poll(); int i=cur[0 ]; if (visited[i]){ continue ; } visited[i]=true ; int l=cur[1 ]; res=Math.max(res,l); String s=words[i]; for (int j = 0 ; j < s.length(); j++) { String sub=s.substring(0 ,j)+s.substring(j+1 ); if (map.containsKey(sub)){ int idx=map.get(sub); if (!visited[idx]){ q.offer(new int []{idx,l+1 }); } } } } return res; }
1235. Maximum Profit in Job Scheduling 注意:
max有两用:代表当前job之前可以append的最大profit ,也最终代表最大profit
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 public int jobScheduling (int [] startTime, int [] endTime, int [] profit) { convert(startTime,endTime,profit); PriorityQueue<int []> pq=new PriorityQueue <>((a,b)->(a[0 ]-b[0 ])); int n=startTime.length; int max=0 ; for (int i = 0 ; i < n; i++) { int start=startTime[i]; int end=endTime[i]; int p=profit[i]; while (!pq.isEmpty() && pq.peek()[0 ]<=start){ max=Math.max(max,pq.poll()[1 ]); } pq.offer(new int []{end,p+max}); } while (!pq.isEmpty()){ max=Math.max(max,pq.poll()[1 ]); } return max; } private void convert (int [] startTime, int [] endTime, int [] profit) { List<int []> list=new ArrayList <>(); int n=startTime.length; for (int i = 0 ; i < n; i++) { list.add(new int []{startTime[i],endTime[i],profit[i]}); } Collections.sort(list,(a,b)->(a[0 ]-b[0 ])); for (int i = 0 ; i < n; i++) { int [] arr=list.get(i); startTime[i]=arr[0 ]; endTime[i]=arr[1 ]; profit[i]=arr[2 ]; } }
1249. Minimum Remove to Make Valid Parentheses 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 public String minRemoveToMakeValid (String s) { int n=s.length(); char [] chars=s.toCharArray(); Deque<Integer> stack=new LinkedList <>(); for (int i = 0 ; i < n; i++) { char c=chars[i]; if (c=='(' ){ chars[i]='.' ; stack.push(i); }else if (c==')' ){ if (!stack.isEmpty()){ chars[stack.pop()]='(' ; }else { chars[i]='.' ; } } } StringBuilder sb=new StringBuilder (); for (int i = 0 ; i < n; i++) { if (chars[i]!='.' ){ sb.append(chars[i]); } } return sb.toString(); }
1099. Two Sum Less Than K 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 public int twoSumLessThanK (int [] nums, int k) { int n= nums.length; Arrays.sort(nums); int res=-1 ; for (int i = n-1 ; i >= 0 ; i--) { if (nums[i]>=k){ continue ; } for (int j = i-1 ; j >= 0 ; j--) { if (nums[i]+nums[j]<k){ res=Math.max(res,nums[i]+nums[j]); break ; } } } return res; }
993. Cousins in Binary Tree 注意定义: have the same depth with different parents.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 Map<Integer,Integer> map; int [] d=new int [2 ];public boolean isCousins (TreeNode root, int x, int y) { map=new HashMap <>(); dfs(root,new int []{x,y},0 ); return d[0 ]==d[1 ] && !map.get(x).equals(map.get(y)); } void dfs (TreeNode node, int [] arr, int cur) { if (node.val==arr[0 ]){ d[0 ]=cur; } if (node.val==arr[1 ]){ d[1 ]=cur; } if (node.left!=null ){ map.put(node.left.val,node.val); dfs(node.left,arr,cur+1 ); } if (node.right!=null ){ map.put(node.right.val,node.val); dfs(node.right,arr,cur+1 ); } }
696. Count Binary Substrings https://leetcode.com/problems/count-binary-substrings/discuss/108625/JavaC%2B%2BPython-Easy-and-Concise-with-Explanation
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public int countBinarySubstrings (String s) { int n=s.length(); List<Integer> list=new ArrayList <>(); int len=1 ; for (int i = 1 ; i < n; i++) { if (s.charAt(i)==s.charAt(i-1 )){ len++; }else { list.add(len); len=1 ; } } list.add(len); int res=0 ; for (int i = 0 ; i < list.size()-1 ; i++) { res+=Math.min(list.get(i),list.get(i+1 )); } return res; }
可以进一步优化为linear scan with constant space:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 public int countBinarySubstrings (String s) { int n=s.length(); int prev=0 ; int cur=1 ; int res=0 ; for (int i = 1 ; i < n; i++) { if (s.charAt(i)==s.charAt(i-1 )){ cur++; }else { res+=Math.min(prev,cur); prev=cur; cur=1 ; } } res+=Math.min(prev,cur); return res; }
992. Subarrays with K Different Integers brute force: LTE
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 public int subarraysWithKDistinct (int [] nums, int k) { int n=nums.length; int res=0 ; Set<Integer> set=new HashSet <>(); for (int i = 0 ; i < n; i++) { set.clear(); set.add(nums[i]); if (set.size()==k){ res++; } for (int j = i+1 ; j < n; j++) { set.add(nums[j]); if (set.size()>k){ break ; } if (set.size()==k){ res++; } } } return res; }
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 public int subarraysWithKDistinct (int [] A, int K) { Map<Integer, Integer> window1 = new HashMap <>(), window2 = new HashMap <>(); int l1 = 0 , l2 = 0 , result = 0 ;for (int r = 0 ; r < A.length; ++r) { window1.put(A[r], window1.getOrDefault(A[r], 0 ) + 1 ); window2.put(A[r], window2.getOrDefault(A[r], 0 ) + 1 ); while (window1.size() > K) { window1.put(A[l1], window1.get(A[l1]) - 1 ); if (window1.get(A[l1]) == 0 ) window1.remove(A[l1]); l1++; } while (window2.size() >= K) { window2.put(A[l2], window2.get(A[l2]) - 1 ); if (window2.get(A[l2]) == 0 ) window2.remove(A[l2]); l2++; } result += l2 - l1; } return result;}
2096. Step-By-Step Directions From a Binary Tree Node to Another 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 int depthStart=0 ;StringBuilder sb=new StringBuilder (); String res=null ; public String getDirections (TreeNode root, int startValue, int destValue) { TreeNode p=lca(root,startValue,destValue); depth(p,startValue,0 ); for (int i = 0 ; i < depthStart; i++) { sb.append('U' ); } trace(p,destValue); return res; } void depth (TreeNode node, int val, int d) { if (node==null ){ return ; } if (node.val==val){ depthStart=d; return ; } depth(node.left,val,d+1 ); depth(node.right,val,d+1 ); } void trace (TreeNode node, int val) { if (node==null ){ return ; } if (node.val==val){ res=sb.toString(); return ; } sb.append("L" ); trace(node.left,val); sb.deleteCharAt(sb.length()-1 ); sb.append("R" ); trace(node.right,val); sb.deleteCharAt(sb.length()-1 ); } TreeNode lca (TreeNode node, int p, int q) { if (node==null || node.val==p || node.val==q){ return node; } TreeNode l=lca(node.left,p,q); TreeNode r=lca(node.right,p,q); if (l!=null && r!=null ){ return node; } return l==null ? r : l; }
1366. Rank Teams by Votes 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 public String rankTeams (String[] votes) { int len=votes[0 ].length(); if (len==1 ){ return votes[0 ]; } Map<Character,int []> map=new HashMap <>(); for (int i = 0 ; i < len; i++) { map.put(votes[0 ].charAt(i),new int [len]); } for (String vote : votes) { for (int i = 0 ; i < len; i++) { char c=vote.charAt(i); map.get(c)[i]++; } } PriorityQueue<Character> pq=new PriorityQueue <>(new Comparator <Character>() { @Override public int compare (Character c1, Character c2) { for (int i = 0 ; i < len; i++) { if (map.get(c1)[i]!=map.get(c2)[i]){ return map.get(c2)[i]-map.get(c1)[i]; } } return c1.compareTo(c2); } }); for (Character c : map.keySet()) { pq.offer(c); } StringBuilder sb=new StringBuilder (); while (!pq.isEmpty()){ sb.append(pq.poll()); } return sb.toString(); }
670. Maximum Swap 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 public int maximumSwap (int num) { String s=String.valueOf(num); char [] chars=s.toCharArray(); for (int i = 0 ; i < chars.length-1 ; i++) { int idx=i+1 ; char max=chars[i+1 ]; for (int j = i+2 ; j < chars.length; j++) { if (chars[j]>=max){ max=chars[j]; idx=j; } } if (max>chars[i]){ char temp=chars[idx]; chars[idx]=chars[i]; chars[i]=temp; break ; } } String res=new String (chars); return Integer.valueOf(res); }
791. Custom Sort String 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public String customSortString (String order, String s) { int [] arr=new int [26 ]; for (int i = order.length()-1 ; i >= 0 ; i--) { char c=order.charAt(i); arr[c-'a' ]=i; } PriorityQueue<Character> pq=new PriorityQueue <>((a,b)->(arr[a-'a' ]-arr[b-'a' ])); for (int i = 0 ; i < s.length(); i++) { pq.offer(s.charAt(i)); } StringBuilder sb=new StringBuilder (); while (!pq.isEmpty()){ sb.append(pq.poll()); } return sb.toString(); }
其实没必要
1293. Shortest Path in a Grid with Obstacles Elimination 反思:
bfs with layer确保了由近及远
只有在较长路径(后出现路径)穿过的障碍更少时,才需要考虑
当允许再穿过的障碍变为-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 public int shortestPath (int [][] grid, int k) { int row=grid.length; int col=grid[0 ].length; int [][] dirs=new int [][]{{0 ,1 },{0 ,-1 },{1 ,0 },{-1 ,0 }}; int [][] lives=new int [row][col]; for (int [] arr : lives) { Arrays.fill(arr,-1 ); } Deque<int []> q=new LinkedList <>(); q.offer(new int []{0 ,0 ,k}); lives[0 ][0 ]=k; int d=0 ; while (!q.isEmpty()){ int size=q.size(); while (size-->0 ){ int [] cur=q.poll(); int i=cur[0 ]; int j=cur[1 ]; int l=cur[2 ]; if (i==row-1 && j==col-1 ){ return d; } if (grid[i][j]==1 ){ l--; } for (int [] dir : dirs) { int x=i+dir[0 ]; int y=j+dir[1 ]; if (x>=0 && x<row && y>=0 && y<col && lives[x][y]<l){ lives[x][y]=l; q.offer(new int []{x,y,l}); } } } d++; } return -1 ; }
1864. Minimum Number of Swaps to Make the Binary String Alternating 倒推法,考察所有可能最终结果与初值的差别
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 public int minSwaps (String s) { int n=s.length(); if (n==1 ){ return 0 ; } int wrong0=0 ; int wrong1=0 ; int res=Integer.MAX_VALUE; for (int i = 0 ; i < n; i++) { char c=s.charAt(i); if (c=='1' && (i&1 )==0 ){ wrong1++; } if (c=='0' && (i&1 )==1 ){ wrong0++; } } if (wrong0==wrong1){ res=Math.min(res,wrong0); } wrong0=0 ; wrong1=0 ; for (int i = 0 ; i < n; i++) { char c=s.charAt(i); if (c=='1' && (i&1 )==1 ){ wrong1++; } if (c=='0' && (i&1 )==0 ){ wrong0++; } } if (wrong0==wrong1){ res=Math.min(res,wrong0); } return res==Integer.MAX_VALUE ? -1 : res; }
2482. Difference Between Ones and Zeros in Row and Column 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 public int [][] onesMinusZeros(int [][] grid) { int row=grid.length; int col=grid[0 ].length; int [] onesRow=new int [row]; int [] onesCol=new int [col]; for (int i = 0 ; i < row; i++) { for (int j = 0 ; j < col; j++) { if (grid[i][j]==1 ){ onesRow[i]++; onesCol[j]++; } } } int [][] res=new int [row][col]; for (int i = 0 ; i < row; i++) { for (int j = 0 ; j < col; j++) { res[i][j]=2 *onesRow[i]-col+2 *onesCol[j]-row; } } return res; }
1335. Minimum Difficulty of a Job Schedule 反思:
初始化为-1,代表第一次处理该子问题
在每个子问题中,初始化res为IntMax,保证小于任何可行结果
在for循环中提前剪枝
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 int [][] dp;public int minDifficulty (int [] nums, int d) { if (nums.length<d){ return -1 ; } dp=new int [nums.length][d+1 ]; for (int [] arr : dp) { Arrays.fill(arr,-1 ); } dfs(nums,0 ,d); return dp[0 ][d]; } int dfs (int [] nums, int i, int d) { if (dp[i][d]!=-1 ){ return dp[i][d]; } if (d==1 ){ int max=0 ; for (int j = i; j < nums.length; j++) { max=Math.max(max,nums[j]); } dp[i][d]=max; return max; } int max=0 ; int res=Integer.MAX_VALUE; for (int j = i; j < nums.length-d+1 ; j++) { max=Math.max(max,nums[j]); res=Math.min(res,max+dfs(nums,j+1 ,d-1 )); } dp[i][d]=res; return res; }
2256. Minimum Average Difference 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 public int minimumAverageDifference (int [] nums) { int n= nums.length; long [] sum=new long [n+1 ]; for (int i = 0 ; i <n; i++) { sum[i+1 ]=sum[i]+nums[i]; } long postSum=0 ; long min=Long.MAX_VALUE; int res=0 ; for (int i = n-1 ; i >= 0 ; i--) { long avg1=sum[i+1 ]/(i+1 ); long avg2=n-i-1 ==0 ? 0 : postSum/(n-i-1 ); long diff=Math.abs(avg1-avg2); if (diff<=min){ res=i; min=diff; } postSum+=nums[i]; } return res; }
692. Top K Frequent Words 1 2 3 4 5 6 7 8 9 10 public List<String> topKFrequent (String[] words, int k) { Map<String,Integer> map=new HashMap <>(); for (String word : words) { map.put(word,map.getOrDefault(word,0 )+1 ); } List<String> list=new ArrayList <>(map.keySet()); Collections.sort(list, (a,b)->(map.get(a)!=map.get(b) ? map.get(b)-map.get(a) : a.compareTo(b))); return list.subList(0 ,k); }
1092. Shortest Common Supersequence 注意:
shortest common supersequence 转化为 longest common subsequence
求出lcs后进行合并
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 public String shortestCommonSupersequence (String str1, String str2) { String s=lcs(str1,str2); int n1=str1.length(); int n2=str2.length(); int p1=0 ; int p2=0 ; StringBuilder sb=new StringBuilder (); for (int i = 0 ; i < s.length(); i++) { while (p1<n1 && str1.charAt(p1)!=s.charAt(i)){ sb.append(str1.charAt(p1)); p1++; } while (p2<n2 && str2.charAt(p2)!=s.charAt(i)){ sb.append(str2.charAt(p2)); p2++; } sb.append(s.charAt(i)); p1++; p2++; } while (p1<n1){ sb.append(str1.charAt(p1)); p1++; } while (p2<n2){ sb.append(str2.charAt(p2)); p2++; } return sb.toString(); } private String lcs (String str1, String str2) { int n1=str1.length(); int n2=str2.length(); String[][] dp=new String [n1+1 ][n2+1 ]; for (String[] arr : dp) { Arrays.fill(arr,"" ); } for (int i = n1-1 ; i >= 0 ; i--) { for (int j = n2-1 ; j >= 0 ; j--) { if (str1.charAt(i)==str2.charAt(j)){ dp[i][j]=str1.charAt(i)+dp[i+1 ][j+1 ]; }else { dp[i][j]= dp[i+1 ][j].length()>=dp[i][j+1 ].length() ? dp[i+1 ][j] : dp[i][j+1 ]; } } } return dp[0 ][0 ]; }
929. Unique Email Addresses 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public int numUniqueEmails (String[] emails) { Set<String> set=new HashSet <>(); for (String email : emails) { String[] split = email.split("@" ); StringBuilder sb=new StringBuilder (); for (int i = 0 ; i < split[0 ].length(); i++) { char c=split[0 ].charAt(i); if (c=='+' ){ break ; } if (c=='.' ){ continue ; } sb.append(c); } set.add(sb.append("@" +split[1 ]).toString()); } return set.size(); }
645. Set Mismatch 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 public int [] findErrorNums(int [] nums) { int n= nums.length; Arrays.sort(nums); int [] res=new int [2 ]; int sum=nums[0 ]; for (int i = 1 ; i < n; i++) { if (res[0 ]==0 && nums[i]==nums[i-1 ]){ res[0 ]=nums[i]; } sum+=nums[i]; } int diff=sum-(1 +n)*n/2 ; res[1 ]=res[0 ]-diff; return res; }
2149. Rearrange Array Elements by Sign 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public int [] rearrangeArray(int [] nums) { int n=nums.length; int [] res=new int [n]; int pos=0 ; int neg=1 ; for (int i = 0 ; i < n; i++) { if (nums[i]>0 ){ res[pos]=nums[i]; pos+=2 ; }else { res[neg]=nums[i]; neg+=2 ; } } return res; }
1047. Remove All Adjacent Duplicates In String 1 2 3 4 5 6 7 8 9 10 11 12 public String removeDuplicates (String s) { StringBuilder sb=new StringBuilder (); for (int i = 0 ; i < s.length(); i++) { char c=s.charAt(i); if (sb.length()>0 && sb.charAt(sb.length()-1 )==c){ sb.deleteCharAt(sb.length()-1 ); }else { sb.append(c); } } return sb.toString(); }
1209. Remove All Adjacent Duplicates in String II brute force: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 public String removeDuplicates (String s, int k) { StringBuilder sb=new StringBuilder (); for (int i = 0 ; i < s.length(); i++) { char c=s.charAt(i); sb.append(c); if (sb.length()-k>=0 ){ int len=sb.length(); String sub= sb.substring(len-k); int j = 0 ; for (; j < sub.length(); j++) { if (sub.charAt(j)!=c){ break ; } } if (j==sub.length()){ sb.delete(len-k,len); } } } return sb.toString(); }
https://leetcode.com/problems/remove-all-adjacent-duplicates-in-string-ii/solution/
好题!
using stack straighforward: 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 public String removeDuplicates (String s, int k) { int n=s.length(); StringBuilder sb=new StringBuilder (); Deque<Integer> stack=new LinkedList <>(); stack.push(1 ); sb.append(s.charAt(0 )); for (int i = 1 ; i < n; i++) { char c=s.charAt(i); if (stack.isEmpty()){ stack.push(1 ); sb.append(c); continue ; } int top= stack.pop(); if (c==sb.charAt(sb.length()-1 )){ top++; stack.push(top); sb.append(c); if (top==k){ sb.delete(sb.length()-k,sb.length()); stack.pop(); } }else { sb.append(c); stack.push(top); stack.push(1 ); } } return sb.toString(); }
only consider last: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 public String removeDuplicates (String s, int k) { int n=s.length(); int [] count=new int [n]; StringBuilder sb=new StringBuilder (); for (int i = 0 ; i < n; i++) { sb.append(s.charAt(i)); int last=sb.length()-1 ; count[last]=1 +(last>0 && sb.charAt(last)==sb.charAt(last-1 ) ? count[last-1 ] : 0 ); if (count[last]>=k){ sb.delete(last-k+1 ,last+1 ); } } return sb.toString(); }
92. Reverse Linked List II unclean code:
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 public ListNode reverseBetween (ListNode head, int left, int right) { ListNode dummy=new ListNode (); dummy.next=head; ListNode pre1=dummy; ListNode p1=head; int idx=1 ; while (idx<left){ idx++; pre1=p1; p1=p1.next; } ListNode p2=p1; while (idx<right){ p2=p2.next; idx++; } ListNode h3=p2.next; p2.next=null ; ListNode h2=reverse(p1); pre1.next=h2; p1.next=h3; return dummy.next; } private ListNode reverse (ListNode node) { if (node==null || node.next==null ){ return node; } ListNode next=node.next; ListNode h=reverse(next); next.next=node; node.next=null ; return h; }
https://leetcode.com/problems/reverse-linked-list-ii/discuss/2311084/JavaC%2B%2B-Tried-to-Explain-every-step
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public ListNode reverseBetween (ListNode head, int left, int right) { ListNode dummy=new ListNode (); dummy.next=head; ListNode pre=dummy; int idx=1 ; while (idx<left){ idx++; pre=pre.next; } ListNode cur=pre.next; ListNode next=null ; for (int i=0 ; i<right-left; i++){ next=cur.next; cur.next=next.next; next.next=pre.next; pre.next=next; } return dummy.next; }
828. Count Unique Characters of All Substrings of a Given String 直接法超时
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 int n;int [] dp;public int uniqueLetterString (String s) { n=s.length(); dp=new int [n]; return dp(s,0 ); } int dp (String s,int i) { if (i==n){ return 0 ; } if (i==n-1 ){ return 1 ; } if (dp[i]!=0 ){ return dp[i]; } int res=dp(s,i+1 ); Map<Character,Integer> map=new HashMap <>(); int cur=0 ; for (int j = i; j < n; j++) { char c=s.charAt(j); map.put(c,map.getOrDefault(c,0 )+1 ); if (map.get(c)==1 ){ cur++; }else if (map.get(c)==2 ){ cur--; } res+=cur; } return dp[i]=res; }
思路:
当char数量有限时,不妨以char出发,考察每个char能unique存在的substring个数
瞻前顾后,计算该char unique存在的区间
https://leetcode.com/problems/count-unique-characters-of-all-substrings-of-a-given-string/discuss/128952/JavaC%2B%2BPython-One-pass-O(N)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 public int uniqueLetterString (String s) { int n=s.length(); int [][] arr=new int [26 ][2 ]; int res=0 ; for (int i = 0 ; i < n; i++) { char c=s.charAt(i); int idx=c-'A' ; if (arr[idx][1 ]==0 && arr[idx][0 ]==0 ){ arr[idx][0 ]=-1 ; }else { res+=(arr[idx][1 ]-arr[idx][0 ])*(i-arr[idx][1 ]); arr[idx][0 ]=arr[idx][1 ]; } arr[idx][1 ]=i; } for (int idx = 0 ; idx < 26 ; idx++) { res+=(arr[idx][1 ]-arr[idx][0 ])*(n-arr[idx][1 ]); } return res; }
2262. Total Appeal of A String https://leetcode.com/problems/total-appeal-of-a-string/discuss/1996390/JavaC%2B%2BPython-Easy-and-Concise-with-Explanation
1 2 3 4 5 6 7 8 9 10 11 12 13 public long appealSum (String s) { int n=s.length(); int [] arr=new int [26 ]; Arrays.fill(arr,-1 ); long res=0 ; for (int i = 0 ; i < n; i++) { char c=s.charAt(i); int idx=c-'a' ; res+=(long )(i-arr[idx])*(n-i); arr[idx]=i; } return res; }
2386. Find the K-Sum of an Array https://leetcode.com/problems/find-the-k-sum-of-an-array/discuss/2465961/Decreasing-Subsequence-Sums
思路:
to find the k-th largest, we just need to find the largest possible sum - k-th smallest
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 public long kSum (int [] nums, int k) { int n=nums.length; long sum=0 ; for (int i = 0 ; i < n; i++) { sum+=nums[i]>0 ? nums[i] : 0 ; nums[i]=Math.abs(nums[i]); } Arrays.sort(nums); PriorityQueue<long []> pq=new PriorityQueue <>((a,b)->((int )(b[0 ]-a[0 ]))); pq.offer(new long []{sum-nums[0 ],0 }); while (--k>0 ){ long [] cur=pq.poll(); sum=cur[0 ]; int idx=(int )cur[1 ]; if (idx+1 <n){ pq.offer(new long []{sum-nums[idx+1 ],idx+1 }); pq.offer(new long []{sum-nums[idx+1 ]+nums[idx],idx+1 }); } } return sum; }
1567. Maximum Length of Subarray With Positive Product 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public int getMaxLen (int [] nums) { int n=nums.length; Map<Integer,Integer> map=new HashMap <>(); map.put(1 ,-1 ); int sum=1 ; int res=0 ; for (int i = 0 ; i < n; i++) { if (nums[i]==0 ){ map.clear(); map.put(1 ,i); sum=1 ; continue ; } sum= nums[i]>0 ? sum : -sum; map.putIfAbsent(sum,i); res=Math.max(res,i-map.get(sum)); } return res; }
妙!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 public int getMaxLen (int [] nums) { int positive = 0 , negative = 0 ; int ans = 0 ; for (int x : nums) { if (x == 0 ) { positive = 0 ; negative = 0 ; } else if (x > 0 ) { positive++; negative = negative == 0 ? 0 : negative+1 ; } else { int temp = positive; positive = negative == 0 ? 0 : negative+1 ; negative = temp+1 ; } ans = Math.max(ans, positive); } return ans; }
2163. Minimum Difference in Sums After Removal of Elements https://leetcode.com/problems/minimum-difference-in-sums-after-removal-of-elements/discuss/1747029/Python-Explanation-with-pictures-Priority-Queue .
10^5 -> nlog(n) -> binary_search / heap
思路:
smallest n from [0,A], biggest n from [A+1,3n-1]
A: [n-1,2n-1], total n+1 possibility
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 public long minimumDifference (int [] nums) { int n=nums.length/3 ; PriorityQueue<Integer> pq1=new PriorityQueue <>((a,b)->(b-a)); long sum=0 ; long [] mins=new long [n+1 ]; for (int i=0 ; i < n; i++) { sum+=nums[i]; pq1.offer(nums[i]); } mins[0 ]=sum; for (int idx = 1 ; idx <=n; idx++) { int i=n+idx-1 ; if (nums[i]<pq1.peek()){ sum-=pq1.poll(); sum+=nums[i]; pq1.offer(nums[i]); } mins[idx]=sum; } long [] maxs=new long [n+1 ]; PriorityQueue<Integer> pq2=new PriorityQueue <>(); sum=0 ; for (int i = 3 *n-1 ; i >= 2 *n; i--) { sum+=nums[i]; pq2.offer(nums[i]); } maxs[n]=sum; for (int idx = n-1 ; idx >= 0 ; idx--) { int i=idx+n; if (nums[i]>pq2.peek()){ sum-= pq2.poll(); sum+=nums[i]; pq2.offer(nums[i]); } maxs[idx]=sum; } long res=Long.MAX_VALUE; for (int idx = 0 ; idx < n + 1 ; idx++) { res=Math.min(res,mins[idx]-maxs[idx]); } return res; }
823. Binary Trees With Factors bottom-up dp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 public int numFactoredBinaryTrees (int [] arr) { Map<Integer,Long> dp=new HashMap <>(); long res=0 ; long mod=(long )1e9 +7 ; Arrays.sort(arr); for (int i = 0 ; i < arr.length; i++) { long cur=1 ; for (int j = 0 ; j < i; j++) { if (arr[i]%arr[j]==0 ){ cur+=dp.get(arr[j])*dp.getOrDefault(arr[i]/arr[j],0L )%mod; } } dp.put(arr[i],cur); res=(res+cur)%mod; } return (int )res; }
1642. Furthest Building You Can Reach https://leetcode.com/problems/furthest-building-you-can-reach/discuss/918515/JavaC%2B%2BPython-Priority-Queue
思路:
it is always optimal to use bricks if possible
first use up ladders
then try to use the smallest amount of bricks to save up a ladder
stop when a gap is unbreachable
i.e, the smallest amount required exceeds what we have
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public int furthestBuilding (int [] heights, int bricks, int ladders) { PriorityQueue<Integer> pq=new PriorityQueue <>(); for (int i=0 ; i < heights.length-1 ; i++) { int d=heights[i+1 ]-heights[i]; if (d>0 ){ pq.offer(d); } if (pq.size()>ladders){ bricks-=pq.poll(); } if (bricks<0 ){ return i; } } return heights.length-1 ; }