Algorithem_Sort#
給定一個按非遞減順序排序的整數數組 nums,返回每個數的平方後按非遞減順序排序的數組。
QuickSort#
實現邏輯:
取指定位置的 index 的值 key,比較 index 和 index 之前的數字,如果前面的數字大於後面的數字,則交換位置;
比如:
[ 8 3 5 1 4 2 ]
從 index 為 1 開始,當前元素 3,前面元素 8,8 > 3,故而交換位置,數組還為[ 3 8 5 1 4 2 ]
然後 index 為 2,當前元素為 5,前面元素為 8,8 > 5,故而交換位置,數組為[ 3 5 8 1 4 2 ]
然後 index 為 3,當前元素為 1,前面元素為 8,8 > 1,故而交換位置,數組為[ 3 5 1 8 4 2 ];5 > 1,故而交換位置,數組為[ 3 1 5 8 4 2 ];3 > 1,故而交換位置,數組為[ 1 3 5 8 4 2 ]
然後 index 為 4,當前元素 4,前面元素為 8,8 > 4,故而交換位置,數組為[ 1 3 5 4 8 2 ];5 > 4,故而交換位置,數組為[ 1 3 4 5 8 2 ]
然後 index 為 5,當前元素 2,前面元素為 8,8 > 2,故而交換位置,數組為[ 1 3 4 5 2 8 ];5 > 2,故而交換位置,數組為[ 1 3 4 2 5 8 ];4 > 2,故而交換位置,數組為[ 1 3 2 4 5 8 ];3 > 2,故而交換位置,數組為[ 1 2 3 4 5 8 ];1 < 2,停止;
代碼如下:
class Solution {
    func sortedSquares(_ nums: [Int]) -> [Int] {
        // first, get the squareList
        var squareNums = nums.map({ $0 * $0 })
        for j in 0..<squareNums.count {
            let key = squareNums[j]
            var i = j - 1
            while (i >= 0 && squareNums[i] > key) {
                squareNums[i+1] = squareNums[i]
                i = i - 1
            }
            squareNums[i+1] = key
        }
        return squareNums
    }
}
Selection Sort#
實現邏輯:
遍歷數組找到最小的值,放到結果數組 index 為 0 的位置;
遍歷數組找到第二小的值,放到結果數組 index 為 1 的位置;
...
代碼如下:
class Solution {
    func sortedSquares(_ nums: [Int]) -> [Int] {
        // first, get the squareList
        var squareNums = nums.map({ $0 * $0 })
        
        // selectionSort
        let count = squareNums.count
        for i in 0..<(count-1) {
            var j_min = i
            var j = i+1
            // 遍歷找出從 i 開始後,最小的元素的 index
            while (j < count) {
                if squareNums[j] < squareNums[j_min] {
                    j_min = j
                } 
                j = j + 1
            }
            
            // 如果 i 和最小的 index 不相等,交換兩個位置的元素
            if i != j_min {
                squareNums.swapAt(i, j_min)
            }
        }
        return squareNums
    }
}
Bubble Sort#
邏輯如下:
依次遍歷相鄰兩個元素,如果前面元素大,則交互位置;然後繼續向後比較;
重複上面步驟
再重複上面步驟
...
直到沒有可交換位置的元素為止
舉例如下:
[2, 1, 6, 4, 7, 5]
第一次遍歷:
index = 1; 當前元素為 2, 前面元素為 1,  2 < 1, 交換位置, [1, 2, 6, 4, 7, 5]
index = 2; 當前元素為 6, 前面元素為 2,  6 > 2, 不需要交換位置
index = 3; 當前元素為 4, 前面元素為 6, 4 < 6, 交換位置, [1, 2, 4, 6, 7, 5]
index = 4; 當前元素為 7, 前面元素為 6, 7 > 6, 不需要交換位置
index = 5; 當前元素為 5, 前面元素為 7, 5 < 7, 交換位置, [1, 2, 4, 6, 5, 7]
中間有交換位置
第二次遍歷:
index = 1; 當前元素為 2, 前面元素為 1, 2 > 1, 不需要交換位置, [1, 2, 4, 6, 5, 7]
index = 2; 當前元素為 4, 前面元素為 2,  4 > 2, 不需要交換位置
index = 3; 當前元素為 6, 前面元素為 4, 6 > 4, 不需要交換位置
index = 4; 當前元素為 5, 前面元素為 6, 5 < 6, 交換位置,  [1, 2, 4, 5, 6, 7]
index = 5; 當前元素為 7, 前面元素為 6, 7 > 6, 不需要交換位置
中間有交換位置
第三次遍歷
index = 1; 當前元素為 2, 前面元素為 1, 2 > 1, 不需要交換位置,  [1, 2, 4, 5, 6, 7]
index = 2; 當前元素為 4, 前面元素為 2,  4 > 2, 不需要交換位置
index = 3; 當前元素為 6, 前面元素為 4, 6 > 4, 不需要交換位置
index = 4; 當前元素為 6, 前面元素為 5, 6 > 5, 不需要交換位置
index = 5; 當前元素為 7, 前面元素為 6, 7 > 6, 不需要交換位置
本次遍歷沒有交換位置,遍歷結束
代碼如下:
class Solution {
    func sortedSquares(_ nums: [Int]) -> [Int] {
        // first, get the squareList
        var squareNums = nums.map({ $0 * $0 })
        
        // bubble sort
        var sorted = false;
        while (!sorted) {
            sorted = true
            for i in 1..<(squareNums.count) {
                if (squareNums[i] < squareNums[i-1]) {
                    squareNums.swapAt(i, i-1)
                    sorted = false
                }
            }
        }
        return squareNums
    }
}
merge sort#
實現邏輯:
把數組拆分為兩半,然後對兩半的數組繼續拆分,直到數組元素個數為 1,然後比較最後拆分的最小數組,排序後返回,再排序拼接拼接拼接。
示意圖如下:

代碼如下:
class Solution {
    func merge(_ left: [Int], _ right: [Int]) -> [Int] {
        // 定義新的數組,用於存儲排序後的結果
        var result: [Int] = []
        // 把傳入參數變為可變
        var mutLeft = left
        var mutRight = right
        // 遍歷排序
        while mutLeft.count > 0 && mutRight.count > 0 {
            // 排序
            // 如果左邊的小,則把左邊第一個元素彈出,放入結果數組中;否則把右邊的第一個元素彈出,放入結果數組中。
            result.append(mutLeft[0] < mutRight[0] ? mutLeft.removeFirst() : mutRight.removeFirst())
        }
        // 拼接不為空的數組
        result += (mutLeft.count > 0 ? mutLeft : mutRight)
        // 返回
        return result
    }
    
    func mergeSort(_ nums: [Int]) -> [Int] {
        // 數組元素個數小於 2,不需要再拆分,返回數組
        if nums.count < 2 {
            return nums
        }
        
        // 從中間拆分數組
        let middle = nums.count / 2
        
        // 取 0 到 middle,不含 middle 的一半數組
        let leftSlice = nums[0..<middle]
        // 然後繼續拆分
        let subLeft = mergeSort(Array(leftSlice))
        
        // 取 middle 右邊的一半數組
        let rightSlice = nums[middle..<nums.count]
        // 繼續拆分
        let subRight = mergeSort(Array(rightSlice))
        // 拆分到不能拆分後,排序、合併後返回
        return merge(subLeft, subRight)
    }
    
    func sortedSquares(_ nums: [Int]) -> [Int] {
        // first, get the squareList
        var squareNums = nums.map({ $0 * $0 })
        
        // merge sort
        return mergeSort(squareNums)
    }
}