1. 程式人生 > >【死磕演算法之1刷leetcode】——Wiggle Sort擺動序列

【死磕演算法之1刷leetcode】——Wiggle Sort擺動序列

題目描述:

Given an unsorted array nums, reorder it in-place such that
nums[0] <= nums[1] >= nums[2] <= nums[3]…
Example:
Given nums = [3, 5, 2, 1, 6, 4], one possible answer is [1, 6, 2, 5, 3, 4].

題目分析

如何生成序列使得nums[0] <= nums[1] >= nums[2] <= nums[3]…?

方法1:交換法 時間複雜度O(n),空間複雜度O(1)

觀察陣列我們可以得到其規律,
設i為nums 的索引,i從1開始:

  1. i為奇數時,nums[i] >=nums[i-1]
  2. i為偶數時,nums [i]< =nums[i-1]

每個值只需要跟前一個值比較,如果不滿足條件,交換一下,讓它滿足條件就好了。
也就是說nums[i] 和 nums[i-2]沒有關係。

舉個例子:
nums = [1,6,3,2,7,8,9]
迭代過程:
i =1:
6>1   符合條件 nums[1]>nums[0]
i = 2:
2<6   符合條件 nums[2]<nums[1]
 i = 3:
3<2  不符合條件  nums[3]>nums[2],將兩者值交換。
 nums=[1,6,2,3,7,8,9]
 i = 4:
7>3  不符合nums[4]<nums[3],將兩者值交換。
 nums = [1,6,2,7,3,8,9]
  i = 5:
8>7  符合nums[5]>nums[4]
 i = 6:
9>8 不符合nums[6]<nums[5],將兩者值交換。
 nums = [1,6,2,7,3,9,8]
 因此wiggle sort最後排序結果為[1,6,2,7,3,9,8]
python實現:
 def wiggleSort1(self, nums):
        # write your code here
        #sort the array
        len1 = len(nums)
        if(len1<=1):
            return
        for i in range(1,len1):#偶數 nums[i]<=nums[i-1] #奇數 nums[i] >= nums[i-1],不符合條件的要交換
            if(i%2==0 and nums[i]>nums[i-1]):
                nums[i], nums[i-1] = nums[i-1],nums[i]
            elif i%2==1 and nums[i] < nums[i-1]:
                 nums[i], nums[i-1] = nums[i-1],nums[i]

方法2:排序法 時間複雜度O(nlog(n)),空間複雜度O(1)

將陣列遞增排序,將第3個元素和第2個元素交換,第5個元素和第4個元素交換…以此類推

仍然舉例nums = [1,6,3,2,7,8,9],排序後nums = [1,2,3,6,7,8,9].
照排序法操作,nums = [1,3,2,7,6,9,8],滿足擺動序列的性質。

python中sort()函式的時間複雜度為O(nlog(n)),遍歷交換時間複雜度為O(n),因此整個方法的時間複雜度取O(nlog(n))

python實現:
 def wiggleSort2(self, nums):
        # write your code here
        # sort the array
        nums.sort()
        len1 = len(nums)
        if (len1 <= 1):
            return
        for i in range(2,len1,2):  #index從2遍歷到len1-1,間隔為2
             nums[i], nums[i - 1] = nums[i - 1], nums[i]

後記:本文在
[Leetcode] Wiggle Sort 搖擺排序的基礎上進行了整理,並增加了python實現程式碼。