public List<Long> minOperations(int[] nums, int[] queries) { List<Long> res=newArrayList<>(); int n=nums.length; Arrays.sort(nums); long[] prefix=newlong[n+1]; //sum of [0,i-1] for (inti=1; i <= n; i++) { prefix[i]=prefix[i-1]+nums[i-1]; } for (int query : queries) { int i=leftSearch(nums,query); //[0,i-1] i prefix[i] //[i,n-1] n-i prefix[n] - prefix[i] long sum=(long)query*i-prefix[i]; sum+=prefix[n]-prefix[i]-(long)query*(n-i); res.add(sum); } return res; }
intleftSearch(int[] nums, int query){ //find the smallest i where nums[i] >=query //if to insert query, it will be placed at i int left=0; int right=nums.length; while(left<right){ //[left,right) int mid=(left+right)/2; if(nums[mid]<query){ left=mid+1; }else{ right=mid; } } return left; }
publiclong[] distance(int[] nums) { int n=nums.length; long[] res=newlong[n]; Map<Integer,List<Integer>> map=newHashMap<>();
for (inti=0; i < nums.length; i++) { map.putIfAbsent(nums[i],newArrayList<>()); map.get(nums[i]).add(i); } //[0,2,3,5] for (Integer num : map.keySet()) { List<Integer> list=map.get(num); int len=list.size(); long[] arr=newlong[len+1];//sum of [0,i-1] for (inti=1; i <= len; i++) { arr[i]=arr[i-1]+list.get(i-1); } //[0,0,2,5,8] for (inti=0; i < len; i++) { int idx=list.get(i); //[0,i-1] //[i+1,len-1] long a=i==0 ? 0 : (long)i*idx-arr[i]; long b=i==len-1 ? 0 : arr[len]-arr[i+1]-(long)(len-i-1)*idx; res[idx]=a+b; } } return res; }
publicintminOperations(int[] nums) { int n=nums.length; int res=Integer.MAX_VALUE; int ones=0; for (inti=0; i < n; i++) { int g=nums[i]; if(g==1){ ones++; } for (intj= i+1; j < n; j++) { g=gcd(g,nums[j]); if(g==1){ //j-i steps to get a 1 //n-1 steps to make all others 1 res=Math.min(res,j-i+n-1); } } } if(ones>0){ res=n-ones; } return res==Integer.MAX_VALUE ? -1 : res; }
privateintgcd(int a, int b){ //4 3 //3 1 //1 0 if(a<b){ return gcd(b,a); } while(b!=0){ int temp=b; b=a%b; a=temp; } return a; }
publicintminimumCost(int[] start, int[] target, int[][] specialRoads) { Map<Integer, HashSet<Integer>> map=newHashMap<>(); PriorityQueue<int[]> pq=newPriorityQueue<>((a,b)->(a[2]-b[2])); pq.offer(newint[]{start[0],start[1],0}); int tx=target[0]; int ty=target[1]; while(!pq.isEmpty()){ int[] cur=pq.poll(); int i=cur[0]; int j=cur[1]; if(i==tx && j==ty){ return cur[2]; } //already reach this point before (by shorter dist) if(map.containsKey(i) && map.get(i).contains(j)){ continue; } map.putIfAbsent(i,newHashSet<>()); map.get(i).add(j); //reach target directly pq.offer(newint[]{tx,ty,cur[2]+tx+ty-i-j}); for (int[] arr : specialRoads) { int x1=arr[0]; int y1=arr[1]; int x2=arr[2]; int y2=arr[3]; //try to use this specialRoad //if the end of this specialRoad has already been reached, //then a shorter path to the end has been found, //no need to consider if(map.containsKey(x2) && map.get(x2).contains(y2)){ continue; } int cost=cur[2]+Math.abs(x1-i)+Math.abs(y1-j)+arr[4]; pq.offer(newint[]{x2,y2,cost}); } } return -1; }
2712. Minimum Cost to Make All Characters Equal
1 2 3 4 5 6 7 8 9 10 11 12 13 14
publiclongminimumCost(String s) { long res=0; int n=s.length(); for (inti=1; i < n; i++) { if(s.charAt(i)!=s.charAt(i-1)){ //i-1,i is different //either flip [0,i-1] or flip [i,n-1] // to make i-1, i the same //after flipping, won't affect following or previous status res+=Math.min(i,n-i); } } return res; }
2713. Maximum Strictly Increasing Cells in a Matrix
publicintmaxIncreasingCells(int[][] mat) { int row=mat.length; int col=mat[0].length; //val -> coordinates TreeMap<Integer, List<int[]>> map=newTreeMap<>(); int[] rows=newint[row];//maximum existing path length ending with this row's point int[] cols=newint[col];//maximum existing path length ending with this col's point int[][] temp=newint[row][col];//maximum existing path ending with this point for (inti=0; i < row; i++) { for (intj=0; j < col; j++) { map.putIfAbsent(mat[i][j],newArrayList<>()); map.get(mat[i][j]).add(newint[]{i,j}); } } for (Integer val : map.keySet()) { for (int[] arr : map.get(val)) { temp[arr[0]][arr[1]]=Math.max(rows[arr[0]],cols[arr[1]])+1; } for (int[] arr : map.get(val)) { rows[arr[0]]=Math.max(rows[arr[0]],temp[arr[0]][arr[1]]); cols[arr[1]]=Math.max(cols[arr[1]],temp[arr[0]][arr[1]]); } } int res=0; for (int i : rows) { res=Math.max(res,i); } for (int i : cols) { res=Math.max(res,i); } return res; }
List<int[]>[] graph; Map<Integer,Integer> count; int[] mask; publiclongcountPalindromePaths(List<Integer> parent, String s) { int n=parent.size(); graph=newList[n]; for (inti=0; i < n; i++) { graph[i]=newArrayList<>(); } for (inti=1; i < n; i++) { graph[parent.get(i)].add(newint[]{i,s.charAt(i)-'a'}); } mask=newint[n]; count=newHashMap<>(); dfs(0,0); long res=0; for (inti=0; i < n; i++) { //must have at least one edge, should not consider (cur,cur) long freq=count.get(mask[i])-1; for (intj=0; j < 26; j++) { int newMask=mask[i]^(1<<j); freq+=count.getOrDefault(newMask,0); } res+=freq; } //considered (u,v) and (v,u), should halve res/=2; return res; }
privatevoiddfs(int cur, int val){ mask[cur]=val; count.put(val,count.getOrDefault(val,0)+1); for (int[] arr : graph[cur]) { int nextIdx=arr[0]; int nextBit=arr[1]; dfs(nextIdx,val^(1<<nextBit)); } }
classSolution { public: string getMinString(string a, string b){ //compare two string with min size or if equal then return lexicographically smaller string return (a.size() < b.size() || (a.size() == b.size() && a < b) )?a : b; } string addTwoStrings(string &a, string &b){ //try to add b at the end of a with optimal way if(b.find(a) != string::npos) return b; for(int i = 0; i < a.size(); ++i){ string t1 = a.substr(i), t2 = b.substr(0, t1.size()); if(t1 == t2) return a + b.substr(t1.size()); } return a+b; } string solve(string& a, string& b, string& c){ //merge a,b first and then merge with c in sequence string t1 = addTwoStrings(a, b), t2 = addTwoStrings(b, a); string res1 = getMinString(addTwoStrings(t1, c), addTwoStrings(c, t1)); string res2 = getMinString( addTwoStrings(t2, c), addTwoStrings(c, t2)); returngetMinString(res1, res2); } string minimumString(string a, string b, string c){ string res = getMinString( solve(a, b, c), solve(b, c, a)); returngetMinString( res , solve(c,a,b)); } };
publiclongfindMaximumElegance(int[][] items, int k) { int n=items.length; Arrays.sort(items,(a,b)->(b[0]-a[0])); long sum=0; Set<Integer> set=newHashSet<>(); LinkedList<Integer> dup=newLinkedList<>(); long res=0; for (inti=0; i < n; i++) { if(i<k){ sum+=items[i][0]; if(set.contains(items[i][1])){ dup.add(items[i][0]); } }elseif(!set.contains(items[i][1])){ if(dup.isEmpty()){ break; } //always update sum when seeing a unique item sum+=items[i][0]-dup.removeLast(); } set.add(items[i][1]); res=Math.max(res,sum+1L*set.size()*set.size()); } return res; }
2817. Minimum Absolute Difference Between Elements With Constraint
reflection:
in paring problems, should always try to use symmetry to avoid duplication
if every i is considered with [0,i-x], then no need to consider i with [i+x,n-1]
find the one key idea of a problem, stay in control of the coding
if already try one way for 20 minutes and no AC, quit and try another one
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
publicintminAbsoluteDifference(List<Integer> nums, int x) { TreeSet<Integer> set=newTreeSet<>(); int n=nums.size(); int res=Integer.MAX_VALUE; //check [0,i-x] for i for (inti= x; i < n; i++) { set.add(nums.get(i-x)); int num=nums.get(i); Integer floor=set.floor(num); if(floor!=null){ res=Math.min(res,num-floor); } Integer ceil=set.ceiling(num); if(ceil!=null){ res=Math.min(res,ceil-num); } } return res; }
//直接暴力backtracking就行,不必要为了dp而dp publicintminimumMoves(int[][] grid) { //if no 0, finished //can always find a solution in finite time, no stack overflow return dfs(grid); }
privateintdfs(int[][] grid){ int tx=0; int ty=0; boolean finished=true; for (inti=0; i < 3; i++) { for (intj=0; j < 3; j++) { if(grid[i][j]==0){ tx=i; ty=j; finished=false; break; } } } if(finished){ return0; } int res=Integer.MAX_VALUE; for (inti=0; i < 3; i++) { for (intj=0; j < 3; j++) { if(grid[i][j]>1){ grid[tx][ty]++; grid[i][j]--; res=Math.min(res,dfs(grid)+Math.abs(i-tx)+Math.abs(j-ty)); grid[tx][ty]--; grid[i][j]++; } } } return res; }