给你两个 非负 整数 num1 和 num2 。
每一步 操作 中,如果 num1 >= num2 ,你必须用 num1 减 num2 ;否则,你必须用 num2 减 num1 。
例如,num1 = 5 且 num2 = 4 ,应该用 num1 减 num2 ,因此,得到 num1 = 1 和 num2 = 4 。然而,如果 num1 = 4且 num2 = 5 ,一步操作后,得到 num1 = 4 和 num2 = 1 。
返回使 num1 = 0 或 num2 = 0 的 操作数 。
提示:
0 <= num1, num2 <= 105
解题思路:简单题直接按题意模拟计数即可
代码和提交结果如下:
class Solution {
public int countOperations(int num1, int num2) {
int count = 0;
while(num1!=0&num2!=0){
if(num1>=num2){
num1 = num1-num2;
}else{
num2 = num2-num1;
}
count++;
}
return count;
}
}
给你一个下标从 0 开始的数组 nums ,该数组由 n 个正整数组成。
如果满足下述条件,则数组 nums 是一个 交替数组 :
nums[i - 2] == nums[i] ,其中 2 <= i <= n - 1 。
nums[i - 1] != nums[i] ,其中 1 <= i <= n - 1 。
在一步 操作 中,你可以选择下标 i 并将 nums[i] 更改 为 任一 正整数。
返回使数组变成交替数组的 最少操作数 。
提示:
1 <= nums.length <= 105
1 <= nums[i] <= 105
解题思路:整体还是模拟,思路分为两条线
① 对数组进行遍历,找出奇数位和偶数位数量最多的数字。
② 如果奇数位和偶数位数量最多的数字相同,直接返回数组总数 - 奇数位最多字母数量 - 偶数维最多字母数量。
③ 如果奇数位和偶数位数量最多的数字相同,则需要重新遍历数组找出 奇数位和偶数维数量第二多的数字。假设奇数位第二多数字数量多,则将其奇数位的其他数字改成第二多的数字,返回(奇数位总数-奇数位第二多数字数量)+ (偶数位总数-偶数维第一多数字数量),反之亦然。
代码和提交结果如下:
class Solution {
public int minimumOperations(int[] nums) {
HashMap<Integer, Integer> ji = new HashMap<>();
HashMap<Integer, Integer> ou = new HashMap<>();
int countJi = 0;
int countOu = 0;
for (int i = 0; i < nums.length; i=i+2) {
ou.put(nums[i],ou.getOrDefault(nums[i],0)+1);
countOu++;
}
for(int i = 1; i < nums.length;i=i+2){
ji.put(nums[i],ji.getOrDefault(nums[i],0)+1);
countJi++;
}
int maxJi = 0;
int numJi = 0;
int maxOu = 0;
int numOu = 0;
for (int i = 0; i < nums.length; i=i+2) {
if(ou.get(nums[i]) > numOu){
numOu = ou.get(nums[i]);
maxOu = nums[i];
}
}
for (int i = 1; i < nums.length; i=i+2) {
if(ji.get(nums[i]) > numJi){
numJi = ji.get(nums[i]);
maxJi = nums[i];
}
}
int count = 0;
if(maxJi!=maxOu){
count = nums.length-numJi-numOu;
}else{
int twoJi = 0;
int numJiTwo = 0;
int twoOu = 0;
int numOuTwo = 0;
for (int i = 0; i < nums.length; i=i+2) {
if(nums[i] == maxOu){
continue;
}
if(ou.get(nums[i]) > numOuTwo){
numOuTwo = ou.get(nums[i]);
twoOu = nums[i];
}
}
for (int i = 1; i < nums.length; i=i+2) {
if(nums[i] == maxJi){
continue;
}
if(ji.get(nums[i]) > numJiTwo){
numJiTwo = ji.get(nums[i]);
twoJi = nums[i];
}
}
if(numOuTwo > numJiTwo){
count = (countOu-numOuTwo) + (countJi-numJi);
}else{
count = (countJi-numJiTwo) + (countOu-numOu);
}
}
return count;
}
}
总结:虽然代码比较臭长,但是好在思路清晰,我是这么安慰自己的,哈哈哈哈。
给你一个 正 整数数组 beans ,其中每个整数表示一个袋子里装的魔法豆的数目。
请你从每个袋子中 拿出 一些豆子(也可以 不拿出),使得剩下的 非空 袋子中(即 至少 还有 一颗 魔法豆的袋子)魔法豆的数目 相等 。一旦魔法豆从袋子中取出,你不能将它放到任何其他的袋子中。
请你返回你需要拿出魔法豆的 最少数目。
提示:
1 <= beans.length <= 105
1 <= beans[i] <= 105
解题思路:前缀和 + 后缀和 + 枚举
① 将数组 bean 按从小到大进行排序
② 从左到右将每个豆子当作最后袋子中剩余的豆子数(这个袋子前面的袋子要清空,后面的袋子豆子数要降到当前正在枚举袋子的豆子数)
前缀和和后缀和可以保证不超时。同时还要记得将所有的 int 在计算之前转为 long,不然会出现数值溢出。
代码和提交结果如下:
class Solution {
public static long minimumRemoval(int[] beans) {
Arrays.sort(beans);
long[] pre = new long[beans.length+1];
pre[0] = 0;
for (int i = 1; i < pre.length; i++) {
pre[i] = pre[i-1] + (long)beans[i-1];
}
long min = Long.MAX_VALUE;
for(int i = 0 ; i < beans.length ; i++){
long temp = pre[i];
temp += pre[beans.length]-pre[i+1];
temp -= (long)beans[i]*(beans.length-i-1);
min = Math.min(temp,min);
}
return min;
}
}
总结:又是掉分的一天,不过学到一些比较实在的东西,加油。