参考刷题顺序: 力扣刷题顺序
453. 最小操作次数使数组元素相等
自己的想法:这个题,想了很久怎么用数组来变化然后分析次数。总是超时,于是乎突然觉得,要是有个数学规律就好了。结果还真的有数学规律。通过的那一刻,满脑子只有:?????代码写的很简单。
public int minMoves(int[] nums) {
int temp=nums.length-1;
Arrays.sort(nums);
int times = 0;
for(int i=temp;i>0;i--){
times += (nums[i]-nums[i-1])*(temp-i+1);
}
return (times);
}
此时此刻的表情:
官方的想法:也是数学想法。每个数-最小的。
class Solution {
public int minMoves(int[] nums) {
int minNum = Arrays.stream(nums).min().getAsInt();
int res = 0;
for (int num : nums) {
res += num - minNum;
}
return res;
}
}
283.移动零
自己的想法:经过上一道题目,突然发觉不能自己吓自己。简单题是不会多难的!还有就是转换一下想法是很重要的。于是乎,把0移动到最后,就是把非零的数值往前排。只要遇到一个非0就往前面排就好了,一个索引j来记录非0的个数。和新建一个数组其实是一样的。
public void moveZeroes(int[] nums) {
int len = nums.length;
int j = 0;
for(int i=0;i<len;i++){
if(nums[i]!=0){
if(i!=j){
nums[j]=nums[i];
nums[i]=0;
}
j++;
}
}
}
官方的想法:都差不多。就不写了。
665. 非递减数列
自己的想法:
这个题真的太难想了。套用一句评论区的话:面向测试用例编程。
首先按照数组的长度来分:数组长度小于3的时候一定是TRUE;数组长度是3的时候,如果nums[i]>nums[i+1],则要对nums[i]修正,修正一次就退出循环,这样就表示只改变了一个元素;当数组长度大于3的时候,如果遇到需要修正的,则要考虑是把nums[i]还是把nums[i+1]修正,取决于nums[i]和nums[i+2]的大小,即需要对趋势分析一下。以确定该修正哪个。说起来有点抽象。画了个图来理解。
public boolean checkPossibility(int[] nums) {
boolean flag=true;
if(nums.length<3) flag =true;
else {
if(nums.length==3){
for(int i=0;i<nums.length-1;i++){
if(nums[i]>nums[i+1]){
nums[i]=nums[i+1];
break;
}
}
}
else {
for(int i=0;i<nums.length-1;i++){
if(nums[i]>nums[i+1] && i<nums.length-2){
if(nums[i]>=nums[i+2]) nums[i] = nums[i+1];
if(nums[i]<nums[i+2]) nums[i + 1] = nums[i];
break;
}
else if(nums[i]>nums[i+1] && i==nums.length-2) nums[i+1]=nums[i];
}
}
for(int i=0;i<nums.length-1;i++){
if(nums[i]>nums[i+1]) flag = false;
}
}
return flag;
其他人的想法:也是比较的思想,但是是跟前面的进行比较。最后是用一个count来记录修改的次数,大于1就不符合题目要求。此时返回false。
public boolean checkPossibility(int[] nums) {
int count = 0;
for (int i = 1; i < nums.length; i++) {
if (nums[i] < nums[i - 1]) {
if (i == 1 || nums[i] >= nums[i - 2]) {
nums[i - 1] = nums[i];
} else {
nums[i] = nums[i - 1];
}
if (++count > 1) {
return false;
}
}
}
return true;
}