学习内容:
665.非递减数列
他人的思路
这道题给了我们一个数组,说我们最多有1次修改某个数字的机会,问能不能将数组变为非递减数组。题目中给的例子太少,不能覆盖所有情况,我们再来看下面三个例子:4,2,3-1,4,2,32,3,3,2,4我们通过分析上面三个例子可以发现,当我们发现后面的数字小于前面的数字产生冲突后,[1]有时候需要修改前面较大的数字(比如前两个例子需要修改4),[2]有时候却要修改后面较小的那个数字(比如前第三个例子需要修改2),那么有什么内在规律吗?是有的,判断修改那个数字其实跟再前面一个数的大小有关系,首先如果再前面的数不存在,比如例子1,4前面没有数字了,我们直接修改前面的数字为当前的数字2即可。而当再前面的数字存在,并且小于当前数时,比如例子2,-1小于2,我们还是需要修改前面的数字4为当前数字2;如果再前面的数大于当前数,比如例子3,3大于2,我们需要修改当前数2为前面的数3。
我的思路
在滑动窗口的时候直接将数字改变好,以减少逻辑的判断,主体的逻辑思路与上面的思路相同.
我的代码
class Solution {public boolean checkPossibility(int[] nums) {int left=0;int right=1;int maxNumber =1;for (int i = 0; i < nums.length-1; i++) {if(nums[left]>nums[right]){maxNumber--;if(maxNumber<0){return false;}if(left==0||nums[left-1]<=nums[right]){nums[left]=nums[right];}else{nums[right]=nums[left];}}left++;right++;}return true;}}
代码思路:
将整个问题抽象为两个数对比之后的值整改情况,得出值得变化取决于第一个与第三数的对比情况,进而在不同的情况下,分别对于nums[left]与nums[right]分别取值.
优解代码
class Solution {public boolean checkPossibility(int[] nums) {//记录更改的次数int cnt = 0;int length = nums.length;for (int i = 1; i<length&&cnt<=1; i++){//如果后数小于前数if (nums[i] < nums[i-1]){//计算变化的次数cnt++;//if(i>=2 && nums[i-2] > nums[i]){nums[i] = nums[i-1];//nums[right]=nums[left]}}}return cnt <= 1;}}
心得
他只考虑了一种结果,即如果前前个大于这个,则改变这个的值.或者说,他不考虑和结果没有关系的值改变,减少了计算的次数,这个只考虑了nums[i]的值变化,至于为啥nums[left]=nums[right]不用考虑,因为前一个变化的left在下一个比较中不会被取值取到,而在作为nums[left-1] 取值中,其的值与右值相当,只会让nums[left]减小,而不会让他加大,所以可以不考虑.
