publicintmaxSubArrayLen(int[] nums, int k) { intcurrSum=0, maxLen = 0; // set initial values for cumulative sum and max length sum to k HashMap<Integer, Integer> sumToIndexMap = newHashMap<Integer, Integer>(); // key: cumulative sum until index i, value: i for (inti=0; i < nums.length; i++) { currSum = currSum + nums[i]; // update cumulative sum // two cases where we can update maxLen if (currSum == k) maxLen = i + 1; // case 1: cumulative sum is k, update maxLen for sure elseif (sumToIndexMap.containsKey(currSum - k)) maxLen = Math.max(maxLen, i - sumToIndexMap.get(currSum - k)); // case 2: cumulative sum is more than k, but we can truncate a prefix of the array // store cumulative sum in map, only if it is not seen // because only the earlier (thus shorter) subarray is valuable, when we want to get the maxLen after truncation if (!sumToIndexMap.containsKey(currSum)) sumToIndexMap.put(currSum, i); } return maxLen; }
publicintmaxSubArrayLen(int[] nums, int k) { Map<Integer,Integer> map=newHashMap<>(); int n=nums.length; int curSum=0; int res=0; for (inti=0; i < n; i++) { curSum+=nums[i]; //[0,i] if(curSum==k){ res=Math.max(res,i+1); }elseif(map.containsKey(curSum-k)){ int index=map.get(curSum-k); //[0,index] //[index+1,i] = k res=Math.max(res,i-index); } if(!map.containsKey(curSum)){ map.put(curSum,i); } } return res; }
I was asked this question in a top company’s onsite interview. I presented this approach specifically the index pair approach like @EddieCarrillo ‘s and the interviewer didn’t buy it. He thought this will not work as when you poll index pair [i, j] out, the next could be [i + 1, j] or [i, j + 1], why did you only add [i, j + 1] to the queue? I tried to explain it in different ways, like thinking it as multiple linked lists, showing an example, and so on. He didn’t agree and still considered this as a wrong approach.
I came back and kept asking myself, how could I have explained this better? Here is they way I would have done:
When index pair [i, j] is polled out from the Priority Queue, it’s guaranteed that there is a pair [i + 1, x] is in the queue. (except its the last pair which we don’t need next pair) Why is it? because we added all the smallest possible pairs [0, 0], [1, 0]…..[Min(k, n), 0]. Now for x, there are three cases:
if x < j, that means [i +1, x] is smaller than [i + 1, j]. Thus, [i + 1, j] won’t be a candidate. And it will be reached later by increasing x in [i + 1, x].
if x > j, that means [i + 1, x] is larger than [i + 1, j]. Thus, [i + 1, j] is already in the result, we should not consider it again.
if x = j, that’s the same pair. We should not add it to queue.
The damage on me is done. I just hope the interviewer come across this post and have an aha moment so that the future interviewees won’t be affected.
法二:想象成有序二维数组 好!
1 2 3 4 5 6 7
# # # # # ? . . # # # ? . . . . # ? . . . . . . "#" means pair already in the output # ? . . . . . . "?" means pair currently in the queue # ? . . . . . . ? . . . . . . . . . . . . . . .
int res=0; int n; publicintcombinationSum4(int[] nums, int target) { Arrays.sort(nums); n=nums.length; for (inti=0; i < n; i++) { backtracking(nums,target-nums[i]); } return res; }
voidbacktracking(int[] nums, int target){ if(target<=0){ if(target==0){ res++; } return; } for (inti=0; i < n; i++) { if(target-nums[i]<0){ break; } backtracking(nums,target-nums[i]); } }
publicinttotalHammingDistance(int[] nums) { int n=nums.length; int res=0; for (inti=0; i < n; i++) { for (intj= i+1; j < n; j++) { res+=hamming(nums[i],nums[j]); } } return res; }
inthamming(int a, int b){ int c=a^b; int res=0; while(c!=0){ if((c&1)==1){ res++; } c>>=1; } return res; }
Approach #2 Loop over the bits! [Accepted]
For each bit position 1-32 in a 32-bit integer, we count the number of integers in the array which have that bit set. Then, if there are n integers in the array and k of them have a particular bit set and (n-k) do not, then that bit contributes k*(n-k) hamming distance to the total.
1 2 3 4 5 6 7 8 9 10
publicinttotalHammingDistance(int[] nums) { inttotal=0, n = nums.length; for (int j=0;j<32;j++) { intbitCount=0; for (int i=0;i<n;i++) bitCount += (nums[i] >> j) & 1; total += bitCount*(n - bitCount); } return total; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14
publicinttotalHammingDistance(int[] nums) { int res=0; int n=nums.length; for (inti=0; i < 32; i++) { int count=0; for (int num : nums) { if((num&(1<<i))!=0){ count++; } } res+=count*(n-count); } return res; }
introw=0, col = 0, pos = 0, m = matrix.length, n=matrix[0].length, output [] = newint[m * n];
for (pos = 0; pos < m * n; pos++) { output[pos] = matrix[row][col];
if ((row + col) % 2 == 0) { // The direction is always up when the sum of row & col is even // For last column, go down if (col == n-1) { row++; } // For first row & non-last columns, go right elseif (row == 0) { col++; } // For not first row & non-last columns, go up and to the right else { row--; col++; }
} else { // The direction is always down when the sum of row & col is odd
// For last row, go right if (row == m-1) { col++; } // For non-last row & first column, go down elseif (col == 0) { row++; } // For non-last row & non-first column, go down and to the left else { row++; col--; } } }
public String addBoldTag(String s, String[] words) { Arrays.sort(words,(a,b)->(b.length()-a.length())); int n=s.length(); int end=0; //[i,end) is bold boolean[] bold=newboolean[n]; for (inti=0; i < n; i++) { for (String word : words) { if(s.startsWith(word,i)){ end=Math.max(end,i+word.length()); break; } } bold[i]=end>i; //神之一手! } StringBuilder sb=newStringBuilder(); for (inti=0; i < n; i++) { if(!bold[i]){ sb.append(s.charAt(i)); continue; } int j=i+1; while(j<n && bold[j]){ j++; } sb.append("<b>"); sb.append(s.substring(i,j)); sb.append("</b>"); i=j-1; } return sb.toString(); }
621. Task Scheduler
greedy
hard to think
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
publicintleastInterval(char[] tasks, int n) { int[] arr=newint[26]; int total=tasks.length; for (char c : tasks) { arr[c-'A']++; } Arrays.sort(arr); int max=arr[25]-1; int idle=max*n; for (inti=24; i >= 0; i--) { if(arr[i]==0){ break; } idle-=Math.min(max,arr[i]); } return total+Math.max(idle,0); }
2365. Task Scheduler II
tasks that need to be completed in order
老老实实 simulation
1 2 3 4 5 6 7 8 9 10 11
publiclongtaskSchedulerII(int[] tasks, int space) { long t=0; Map<Integer,Long> next=newHashMap<>(); //next starting time for (int task : tasks) { long time=next.containsKey(task) ? next.get(task) : 0; t=Math.max(t,time); t++; next.put(task,t+space); } return t; }
769. Max Chunks To Make Sorted
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
publicintmaxChunksToSorted(int[] arr) { //1 0 2 3 4 //4 1 2 3 0 //arr[0,i] should be 0,1,2,...,i int count=0; int max=0; int n=arr.length; for (inti=0; i < n; i++) { max=Math.max(max,arr[i]); if(i==max){ count++; } } return count; }
768. Max Chunks To Make Sorted II
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
publicintmaxChunksToSorted(int[] arr) { int n=arr.length; int[] rightMin=newint[n]; rightMin[n-1]=arr[n-1]; for (inti= n-2; i >= 0; i--) { rightMin[i]=Math.min(rightMin[i+1],arr[i]); } int res=1; int leftMax=0; for (inti=0; i < n-1; i++) { leftMax=Math.max(leftMax,arr[i]); if(leftMax<=rightMin[i+1]){ res++; } } return res; }
public List<Integer> findClosestElements(int[] arr, int k, int x) { PriorityQueue<Integer> q=newPriorityQueue<>(newComparator<Integer>() { @Override publicintcompare(Integer a, Integer b) { int v1=Math.abs(a-x); int v2=Math.abs(b-x); return v1==v2 ? a-b : v1-v2; } }); for (int num : arr) { q.offer(num); } List<Integer> res=newArrayList<>(); int i=0; while(i++<k){ res.add(q.poll()); } Collections.sort(res); return res; }
化劲儿:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
public List<Integer> findClosestElements(int[] arr, int k, int x) { int low=0; int high=arr.length-1; while(high-low+1>k){ if(Math.abs(arr[high]-x)<Math.abs(arr[low]-x)){ low++; }else{ high--; } } List<Integer> res=newArrayList<>(); for(int i=low; i<=high; i++){ res.add(arr[i]); } return res; }