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
| public int generateKey(int num1, int num2, int num3) { List<Integer> numList = List.of(num1, num2, num3); ArrayList<String> strings = new ArrayList<>(); numList.forEach(num->{ StringBuilder s = new StringBuilder(Integer.toString(num)); int count = 4 - s.length(); for(int i = 0;i < count;i++){ s.insert(0, "0"); } strings.add(String.valueOf(s)); }); StringBuilder builder = new StringBuilder(); for(int i = 0;i < 4;i++){ int min = Character.MAX_VALUE; for(int j = 0;j < 3;j++){ String s = strings.get(j); min = Math.min(min,s.charAt(i) - '0'); } builder.append(min); } return Integer.parseInt(builder.toString()); }
|
2. 从最低位开始计算
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public int generateKey(int num1, int num2, int num3) { int ans = 0; int pow = 1; for (int i = 0; i < 4; i++) { int t = Math.min(num1 % 10, num2 % 10); int min = Math.min(t, num3 % 10); ans = ans + min * pow; num1 /= 10; num2 /= 10; num3 /= 10; pow *= 10; } return ans; }
|
思路就是用分别用一个计数器,分别记录0和(0,1)出现的次数,此时n0就是到目前为止出现的最后一个0的下标,n1同理。然后总是假设当前这块板是蓝色的,为它刷上蓝色,接着判断当前值是否等于1,如果是,则把它刷为白色,0也是同理,类似刷油漆的过程,旧的会被新的覆盖。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| public void sortColors(int[] nums) { int n0 = 0; int n1 = 0; for(int i = 0;i < nums.length;i++){ int num = nums[i]; nums[i] = 2; if(num < 2){ nums[n1++] = 1; } if(num < 1){ nums[n0++] = 0; } } }
|
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 long countSubarrays(int[] nums, int minK, int maxK) { long ans = 0; int minIndex = -1; int maxIndex = -1; int left = 0; for(int i = 0;i < nums.length;i++){ int num = nums[i]; if(num == minK){ minIndex = i; } if(num == maxK){ maxIndex = i; } if( num > maxK || num < minK){ left = i+1; minIndex = -1; maxIndex = -1; } else if(minIndex != -1 && maxIndex != -1){ ans += Math.min(maxIndex, minIndex) - left + 1; } } return ans; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| public long countSubarrays(int[] nums, long k) { int left = 0; long sum = 0; long ans = 0; for(int right = 0;right < nums.length;right++){ int num = nums[right]; sum += num; while (sum * (right - left + 1) >= k){ sum -= nums[left]; left++; } ans += right - left + 1; } return ans; }
|
这道题目和前面的那些滑动窗口题目类似,先是扩张窗口使得窗口内最大元素个数为k,然后在内循环中收缩窗口,直至窗口内最大元素个数为k-1(此时是窗口恰好不满足的情况)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| public long countSubarrays(int[] nums, int k) { int max = Arrays.stream(nums).max().getAsInt(); int left = 0; long ans = 0; int count = 0; for(int right = 0;right < nums.length;right++){ int num = nums[right]; if(num == max){ count++; } while (count >= k){ if(nums[left] == max){ count--; } left++; } ans += left; } return ans; }
|
这道题目是贪心算法思想,在划分时如果包含一个字符,则该次划分必须包含所有字符。
算法步骤:
1:计算字符串s中每个字符最后一次出现的位置。
2:对字符串进行遍历,在遍历中不断更新右窗口最大下标。
3:当到达右窗口时,统计当前划分,重新赋值,开始下一轮划分。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| public List<Integer> partitionLabels(String s) { int n = s.length(); int[] maxIndex = new int[26]; for(int i = 0;i < n;i++){ maxIndex[s.charAt(i) - 'a'] = i; } ArrayList<Integer> ans = new ArrayList<>(); int left = 0,right = 0; for(int i = 0;i < n;i++){ char c = s.charAt(i); right = Math.max(right,maxIndex[c - 'a']); if(i == right){ ans.add(right - left + 1); left = i+1; } } return ans; }
|
1.直接统计位数
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public int findNumbers(int[] nums) { int ans = 0; for(int num : nums){ int count = 0; while (num > 0){ count++; num /= 10; }; if (count % 2 == 0){ ans++; } } return ans; }
|

2.使用对数函数
以10为底的对数函数向下取整为int可以获取除了第一位之外的位数,对结果加一即可获取x的位数。
1 2 3 4 5 6 7 8 9 10
| public int findNumbers(int[] nums) { int ans = 0; for(int num : nums){ int count = (int) Math.log10(num) + 1; if(count % 2 == 0){ ans++; } } return ans; }
|
