上岸 I LeetCode Weekly Contest 227解题报告 算法 刷题解法

卖大米 2021-2-8 513


No.1 检查数组是否经排序和轮转得到

解题思路

枚举、检查。

代码展示


class Solution { 
   public boolean check(int[] nums) { 
       for (int i = 0; i < nums.length; i++) { 
           if (check(nums, i)) { 
               return true; 
           } 
       } 
       return false; 
   } 

   private boolean check(int[] nums, int i) { 
       for (int j = 1; j < nums.length; j++) { 
           if (nums[(i + j - 1 + nums.length) % nums.length] > nums[(i + j) % nums.length]) { 
               return false; 
           } 
       } 
       return true; 
   } 
}

No.2 移除石子的最大得分

解题思路

贪心,每次移除最多的和最少的。

代码展示


class Solution { 
   public int maximumScore(int a, int b, int c) { 
       int res = 0; 
       int[] nums = {a, b, c}; 
       Arrays.sort(nums); 
       for (; nums[1] != 0; res++) { 
           if (nums[0] == 0) { 
               nums[1]--; 
           } else { 
               nums[0]--; 
           } 
           nums[2]--; 
           Arrays.sort(nums); 
       } 
       return res; 
   } 
}

No.3 构造字典序最大的合并字符串

解题思路

贪心,详见注释。

代码展示


class Solution { 
   public String largestMerge(String word1, String word2) { 
       StringBuilder sb = new StringBuilder(); 
       for (int i = 0, j = 0; i < word1.length() || j < word2.length(); ) { 
           // word1[i] != word2[j] 时, 选择大的字符 
           if (i == word1.length()) { 
               sb.append(word2.charAt(j++)); 
           } else if (j == word2.length()) { 
               sb.append(word1.charAt(i++)); 
           } else if (word1.charAt(i) > word2.charAt(j)) { 
               sb.append(word1.charAt(i++)); 
           } else if (word1.charAt(i) < word2.charAt(j)) { 
               sb.append(word2.charAt(j++)); 
           } else { 
               // word1[i] == word2[j] 时 
               // 找到第一个不相等的 word1[i + t] != word2[j + t] 
               // 选择大的字符所在的字符串 
               Character c1 = null, c2 = null; 
               for (int t = 1; i + t < word1.length() && j + t < word2.length(); t++) { 
                   if (word1.charAt(i + t) != word2.charAt(j + t)) { 
                       c1 = word1.charAt(i + t); 
                       c2 = word2.charAt(j + t); 
                       break; 
                   } 
               } 
               // 若后续全都相等,选择长的 
               if (c1 == null && word1.length() - i > word2.length() - j) { 
                   sb.append(word1.charAt(i++)); 
               } else if (c1 == null && word1.length() - i < word2.length() - j) { 
                   sb.append(word2.charAt(j++)); 
               } else if (c1 != null && c1 > c2) { 
                   sb.append(word1.charAt(i++)); 
               } else { 
                   sb.append(word2.charAt(j++)); 
               } 
           } 
       } 
       return sb.toString(); 
   } 
}

No.4 最接近目标值的子序列和

解题思路

超大背包问题。

代码展示


class Solution { 
   public int minAbsDifference(int[] nums, int goal) { 
       int n = nums.length; 
       int half = n / 2; 
       int[] a = new int[1 << half]; 
       for (int i = 0; i < (1 << half); i++) { 
           int sum = 0; 
           for (int j = 0; j < half; j++) { 
               if (((i >> j) & 1) > 0) { 
                   sum += nums[j]; 
               } 
           } 
           a[i] = sum; 
       } 
       int half2 = n - half; 
       int[] b = new int[1 << half2]; 
       for (int i = 0; i < (1 << half2); i++) { 
           int sum = 0; 
           for (int j = 0; j < half2; j++) { 
               if (((i >> j) & 1) > 0) { 
                   sum += nums[half + j]; 
               } 
           } 
           b[i] = sum; 
       } 
       Arrays.sort(b); 
       int ans = Integer.MAX_VALUE; 
       for (int v : a) { 
           int pos = binarySearch(b, goal - v); 
           for (int j = Math.max(0, pos - 2); j < Math.min(b.length, pos + 2); j++) { 
               ans = Math.min(ans, Math.abs((v + b[j]) - goal)); 
           } 
       } 
       return ans; 
   } 

   public static int binarySearch(int[] nums, int key) { 
       int start = 0, end = nums.length - 1; 
       while (start + 1 < end) { 
           int mid = (start + end) / 2; 
           if (nums[mid] < key) { 
               start = mid; 
           } else { 
               end = mid; 
           } 
       } 
       return nums[start] < key ? end : start; 
   } 
}

最新回复 (0)
返回