第一题:环和杆

题目描述

image.png

思路

存储每个位置出现的颜色值的集合,统计集合的大小等于3的位置个数,返回即可。

代码

  1. var countPoints = function(rings) {
  2. let len =rings.length;
  3. let dp =new Array(10).fill(0).map(v=>new Set());// 表示第i个位置上集齐的颜色
  4. for(let i =0 ;i < len;i += 2){
  5. dp[+rings[i+1]].add(rings[i]);
  6. }
  7. let res=0;
  8. for(let i =0 ;i < 10;i++){
  9. if(dp[i].size == 3)res++;
  10. }
  11. return res;
  12. };

第二题:子数组的范围和

描述

image.png

思路

遍历每个区间,求出最大值和最小值,然后累加最大值和最小值的差值,最后返回累加结果。
使用双重循环遍历区间,其中外循环遍历i作为区间的开始位置,内循环遍历j作为区间的结束位置。
遍历过程中满足dp[i,j] = max(max[i, j-1], nuns[j] ); 其中dp[i,j]表示区间[i,j]中的最大值。
区间最小值同理。

代码

  1. var subArrayRanges = function(nums) {
  2. const n =nums.length;
  3. let sum = 0;
  4. let min,max;
  5. for(let i =0 ;i < n;i++){
  6. min = nums[i];
  7. max = nums[i];
  8. for(let j = i + 1 ;j < n; j++){
  9. min = nums[j] < min? nums[j]:min;
  10. max = nums[j] > max? nums[j]:max;
  11. sum += max - min;
  12. }
  13. }
  14. return sum;
  15. };

第三题:给植物浇水 II

描述

image.png

思路

双指针两边向中间夹,直接模拟。

代码

  1. var minimumRefill = function(plants, capacityA, capacityB) {
  2. const n=plants.length;
  3. let l=0, r = n-1;
  4. let a = capacityA, b = capacityB;
  5. let cnt=0;
  6. while(l < r){
  7. if(a >= plants[l]){
  8. a -= plants[l];
  9. }else{
  10. a = capacityA - plants[l];
  11. cnt++;
  12. }
  13. l++;
  14. if(b >= plants[r]){
  15. b -= plants[r];
  16. }else{
  17. b = capacityB - plants[r];
  18. cnt++;
  19. }
  20. r--;
  21. }
  22. if(l == r && ( a >= plants[l] || b >= plants[l]))return cnt;
  23. else if(l == r)return cnt+1;
  24. return cnt;
  25. };

第四题:摘水果

描述

image.png

思路

先求出 前缀和,然后遍历可行的区间,得出各个可行区间和,得出最大的区间和即可。
注意: 只要是区间和问题,一律先求出前缀和

代码

  1. var maxTotalFruits = function(fs, start, k) { // 只要是区间和,就一定要求 前缀和
  2. const n = fs.length;
  3. const pre = []; //求出前缀和 ,
  4. const pos = fs[n-1][0];
  5. for(let i = 0, j=0; i <= pos; i++){
  6. if( i==0 && fs[j][0]==0 ){
  7. pre[0] = fs[j++][1];
  8. }else if(i == 0){
  9. pre[0] = 0;
  10. }else if(fs[j][0] == i){
  11. pre[i] = pre[i-1] + fs[j][1];
  12. j++;
  13. }else{
  14. pre[i] = pre[i-1];
  15. }
  16. }
  17. if(k == 0){
  18. if(start > pos) return 0;
  19. if(start == 0) return pre[0];
  20. return pre[start] - pre[start-1];
  21. }
  22. let res = Math.max(get(k, 0), get(0,k));
  23. for(let i= k ; i > 0; i--){
  24. let left = get( i, k - 2*i);
  25. let right = get(k-2*i, i);
  26. res=_.max([res,left,right]);
  27. }
  28. return res;
  29. function get( l, r){ // 返回区间l 到 r之间的区间和
  30. if(r < 0) r = 0;
  31. if(l < 0) l = 0;
  32. if(start - l - 1 < 0 && start + r > pos){
  33. return pre[pos];
  34. }else if(start-l-1 < 0){
  35. return pre[start+r]
  36. }
  37. else if(start+r > pos) {
  38. return pre[pos] - pre[start-l-1];
  39. }
  40. return pre[start+r] - pre[start-l-1];
  41. }
  42. };