原理:選取一個數,使得這個數的左邊比這個數小,右邊的數比這個數大。
接下來的問題是如果實現這個過程。
第一種用棧做
用棧做就太簡單了。
直接鎖定1。
從3開始往後找。
找到小的數,直接插入到1的前面。
再對每一部分進行遞歸。
這裏是找到了 0 0,新序列是 0 0 1 3 6 2 8 4 8
接下來就是 0 0裏找
再是3 6 2 8 4 8裏找。
。。。
這裏用List模擬的棧
// 136284008List實現太輕鬆了 void calculate(List<Integer> list, int startIndex, int endIndex) {// origin index 0 size-1 if (startIndex == endIndex || startIndex + 1 == endIndex) { return; } int firstNum = list.get(startIndex); int index = startIndex; for (int i = startIndex + 1; i <= endIndex; i++) { int num = list.get(i); if (num < firstNum) { list.add(startIndex, num); list.remove(i + 1); index++; } } calculate(list, startIndex, index - 1); calculate(list, index + 1, endIndex); }
第二種用數組做,略微麻煩一點。
沒有List那麼方便,需要挖坑。
我們依然選取1作爲參照數。
用X保存這個1。1就彷彿成了一個被挖出來的坑,因爲他的數已經被保存了,所以這個位置上可以任意賦值了。
之後從最後一位開始找比1小的數。8不符合。0是符合的。
所以這個0就填到剛剛第一位的坑裏,而0的那個位置有多出來一個坑。
接下來就是要從左邊開始找大的數,3直接就符合了。放到剛剛0的坑裏。而3又多出來一個坑。
接下來又是從右邊找。。。直到左右相遇。
//數組實現 void calculate(int a[], int startIndex, int endIndex) { if (startIndex == endIndex || startIndex + 1 == endIndex || startIndex > endIndex) { return; } int x = a[startIndex]; int ken = startIndex; int s = startIndex; int e = endIndex; startIndex ++; boolean flag = true; while (startIndex <= endIndex) { if (flag) { if (x > a[endIndex]) { a[ken] = a[endIndex]; ken = endIndex; flag = false; } endIndex --;//0 } else { if (x < a[startIndex]) { a[ken] = a[startIndex]; ken = startIndex; flag = true; } startIndex ++; } } a[ken] = x; calculate(a, s, ken - 1); calculate(a, ken + 1, e); }