1. 程式人生 > >280. Wiggle Sort/324. Wiggle Sort II

280. Wiggle Sort/324. Wiggle Sort II

ron correct pre 如果 += == div cond pri

280 Given an unsorted array nums, reorder it in-place such that nums[0] <= nums[1] >= nums[2] <= nums[3]....

Example:

Input: nums = [3,5,2,1,6,4]
Output: One possible answer is [3,5,1,6,2,4]

280要求的是可以大於等於,其實簡單。

方法一:
1. 先排序,得到序列 a0<=a1<=a2<=a3<=a4....<ai<=ai+1
2. 然後從a1 開始,交換相鄰的, 這樣就會有a0<=a2>=a1<=a4>=a3<=an
class Solution {
    public void wiggleSort(int[] nums) {
       
        Arrays.sort(nums);
        
        for(int i=1; i<nums.length-1; i+=2){
            swap(nums, i,i+1);
        }
    }
    
    private void swap(int[] nums, int i, int j){
        int tmp = nums[i];
        nums[i] = nums[j];
        nums[j] 
= tmp; } }

方法二: 上面的方法是 nlogn解法, 如何尋求一個On 的解法。

對於O(n) 顯然只能掃描一遍數組,具體算法如下:

1. 在even index 上,比如index = 0, 如果 nums[i] > nums[i+1], 就交換

2. 在odd index 上, 比如index=1, 如果 nums[i] <nums[i+1] 就交換。

如何證明這個算法的正確性,用數學歸納法 Mathematical Induction, 可以證明。

證明如下: 假設已經用上面算法進行了排序,得到了:

a0<=a1>=a2<=a3>=a4<=....ak...

對於n = k+1 的情況,

if n = k+1 is even( 偶數需要在小的位置上), 說明 ak>=a(k+1) ,

如果 a(k+1) > a(k+2), 進行交換, 得到 ak >= a(k+2) <=a(k+1), 可以保持序列形狀

如果a(k+a) <a(k+2) ,不用交換, 仍然可以保持ak<=a(k+1)<=a(k+2) , the order is also correct.

同理, if n =k+1 is odd ,仍然可以用歸納法證明。

class Solution {
    public void wiggleSort(int[] nums) {
        
     for(int i=0; i<nums.length-1; i++){
         if(i%2 ==0 && nums[i] > nums[i+1]  || i%2==1 && nums[i] <nums[i+1])  {   //the condition need to swap
             swap(nums,i,i+1);
         }     
      }
        
    }
    
    private void swap(int[] nums, int i, int j){
        int tmp = nums[i];
        nums[i] = nums[j];
        nums[j] = tmp;
    }
}

對於324 把等於號去掉,保持嚴格的遞增或者遞減順序:

Given an unsorted array nums, reorder it such that nums[0] < nums[1] > nums[2] < nums[3]....

去掉等於號,難度增加了很多,畢竟就算直接排序好了,也難保持嚴格遞增。

280. Wiggle Sort/324. Wiggle Sort II