給定一個序列,詢問是否能刪除一個數讓它成為非遞減或者非遞增的序列。
nlogn一直過不了,所以選擇了以下方式。。。
因為刪除一個嘛,先證明刪除一個能不能是非遞減的(非遞增的把序列倒過來搞一次就行了)
首先,對一個序列前後兩個數做差
比如說序列
3 1 4 1 5 做差後(即1-3,4-1,1-4,5-1)是 -2,3,-3,4。發現有2個負數,那就不行。
如果序列是 3 1 1 5。 做差後是-2,0,4。發現有一個負數,是在頭部,可以刪掉
如果序列是5 6 3 ,7 7,做差後是 1,-3,4,0。發現有一個負數,而且可以跟左右兩邊的某個數相加變成正數,那麼這個3就可以刪掉。
如果序列是1 2 3 4,做差後是1,1,1,1 沒有負數,本身就可以是非遞減。
能看得出來:
做差後的序列:如果有2個及以上負數,那它肯定不可能是非遞減。
如果有一個負數,它在頭或者尾,或者在中間而且可以跟左右兩邊任意一個數相加是非負數,即可以是非遞減
如果沒有負數,已經是非遞減
時間複雜度是O(N),額外需要O(N)的空間存做差後的陣列
非遞增的話就把陣列倒一下再來一次就行了。
https://www.cnblogs.com/Esquecer/p/9013331.html
import java.io.*; public class Main { public static int shu(int[] xx) { int[] res = new int[xx.length-1]; for (int i = 1; i < xx.length; i++) { res[i-1] = xx[i]-xx[i-1]; } int cnt = 0; for (int i = 0; i < res.length; i++) { if (res[i]<0) { cnt++; if (cnt==1) { if (i==0||i==res.length-1) { continue; }else { if (res[i]+res[i-1]>=0 || res[i]+res[i+1]>=0) { continue; }else { return 0; } } } if (cnt==2) { return 0; } } } return 1; } public static void main(String[] args)throws IOException { // TODO 自動生成的方法存根 StreamTokenizer sc = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in))); sc.nextToken(); //輸入前記得加 int n=(int)sc.nval; for (int i = 0; i < n; i++) { sc.nextToken(); //輸入前記得加 int nn = (int)sc.nval; int[] x1 = new int[nn]; int[] x2 = new int[nn]; for (int j = 0; j < nn; j++) { sc.nextToken(); //輸入前記得加 int yy = (int)sc.nval; x1[j] = yy; } for (int j = 0; j < nn; j++) { x2[j] = x1[nn-1-j]; } int a1 = shu(x1); if (a1==1) { System.out.println("YES"); continue; } int a2 = shu(x2); if (a2==1) { System.out.println("YES"); }else { System.out.println("NO"); } } } }