NonDecreasingArray [source code]
public class NonDecreasingArray {
static
/******************************************************************************/
class Solution {
public boolean checkPossibility(int[] nums) {
int count = 0;
for (int i = 0; i < nums.length - 1; i++)
if (!(nums[i] <= nums[i + 1])) {
if (count > 0)
return false;
if (i - 1 >= 0 && i + 2 < nums.length && (nums[i] > nums[i + 2] && nums[i + 1] < nums[i - 1]))
return false;
count++;
}
return true;
}
}
/******************************************************************************/
public static void main(String[] args) {
NonDecreasingArray.Solution tester = new NonDecreasingArray.Solution();
int[][] inputs = {
{3,4,2,3}, {0},
{2,3,3,2,4}, {1},
{1,3,5,2,4}, {0},
};
for (int i = 0; i < inputs.length / 2; i++) {
int[] nums = inputs[2 * i];
boolean ans = inputs[1 + 2 * i][0] == 1;
System.out.println(Printer.separator());
boolean output = tester.checkPossibility(nums);
System.out.println(
Printer.wrapColor(Printer.array(nums), "magenta") +
" -> " + output +
Printer.wrapColor(", expected: " + ans, ans == output ? "green" : "red")
);
}
}
}
还是从笨办法开始做; 刚开始写了一个很trivial的做法, 就是数一下downtick的个数, 只要不超过1就是true; 但是这个思路立刻被inputs的第一个给break了; 当然, 这个错误的思路还是有帮助的;
Google的题目还是那个特点, 你想的多美的算法最后人家都能找一个corner case给你break掉; 这个题目大体的思路其实很早就有了, 关键是怎么调整; 不过这个题目本身还是很有意思的: 看上去是一个很trivial的题目, 但是最后OJ引导你一步一步的走向对题目的正确的intuition;
刚开始的想法是, 只要不超过一个downtick就行了, 但是这个不对; 然后思考, 这里的modify是什么意思, 然后怀疑, 只要downtick的左右两边的两个数字维持nondecreasing就行了, 但是这个其实也不对; 最后才发现, downtick两边的两个邻居形成的这个范围是一个关键; 要保证只要modify一个element就能进入全体non-decreasing, 必须保证修改一个downtick的两个端点当中的一个之后, 两个端点都能够维持在这两个邻居围成的这个range当中; 所以只要保证downtick的两个端点不同时超界就行了;
最后的速度是30ms (N/A), 这个题目总体还是挺好玩的; 真正面试的时候碰到, 只要不慌, 应该能做出来, 关键是如果之前的intuition被break了, 就要trace the error, 重新apply之前错误的逻辑, 想想为什么这个case你的逻辑就不对; 在此基础上收集思想, 来获得a closer intuition;
另外, 写的时候你每一个iteration对应的其实是一个index, 一个i, 但是你却要讨论的是一个downtick, 那么这个downtick的做右端点对应的分别是多少? 这个要时刻提醒自己一下;
这个是discussion上面一个所谓的greedy解法, 虽然我认为并不如我自己的解法:
@Hao-Cai said in [Java/C++] Simple greedy like solution with explanation:
This problem is like a greedy problem. When you find
nums[i-1] > nums[i]
for somei
, you will prefer to changenums[i-1]
's value, since a largernums[i]
will give you more risks that you get inversion errors after positioni
. But, if you also findnums[i-2] > nums[i]
, then you have to changenums[i]
's value instead, or else you need to change both ofnums[i-2]
's andnums[i-1]
's values.Java version:
public boolean checkPossibility(int[] nums) {
int cnt = 0; //the number of changes
for(int i = 1; i < nums.length && cnt<=1 ; i++){
if(nums[i-1] > nums[i]){
cnt++;
if(i-2<0 || nums[i-2] <= nums[i])nums[i-1] = nums[i]; //modify nums[i-1] of a priority
else nums[i] = nums[i-1]; //have to modify nums[i]
}
}
return cnt<=1;
}
C++ version:
bool checkPossibility(vector<int>& nums) {
int cnt = 0; //the number of changes
for(int i = 1; i < nums.size() && cnt<=1 ; i++){
if(nums[i-1] > nums[i]){
cnt++;
if(i-2<0 || nums[i-2] <= nums[i])nums[i-1] = nums[i]; //modify nums[i-1] of a priority
else nums[i] = nums[i-1]; //have to modify nums[i]
}
}
return cnt<=1;
}
这个思路本身其实总体是没有问题的, 看一看学一学也没毛病;
这个是另外一个类似我的, 不需要modify input的解法;
class Solution {
public boolean checkPossibility(int[] a) {
int modified = 0;
for (int i = 1, prev = a[0]; i < a.length; i++) {
if (a[i] < prev && modified++ > 0) return false;
if (a[i] < prev && i - 2 >= 0 && a[i - 2] > a[i]) continue;
prev = a[i];
}
return true;
}
}
其实我想想他这个想法是比我的思路更直接的, 而且他这个思路可以认为是被modify的解法inspire过来的, 所以是有一个成长性的思路在里面的, 很不错;
这个题目还是太新了, 目前discussion并没有很多其他更好的解法, 暂时不管了;
Problem Description
Given an array with n integers, your task is to check if it could become non-decreasing by modifying at most 1 element.
We define an array is non-decreasing if array[i] <= array[i + 1] holds for every i (1 <= i < n).
Example 1:
Input: [4,2,3]
Output: True
Explanation: You could modify the first
4
to
1
to get a non-decreasing array.
Example 2:
Input: [4,2,1]
Output: False
Explanation: You can't get a non-decreasing array by modify at most one element.
Note: The n belongs to [1, 10,000].
Difficulty:Easy
Total Accepted:2K
Total Submissions:11.2K
Contributor: Stomach_ache
Companies
google
Related Topics
array