LeetCode—1. Quick sorting algorithm

1. Basic idea

  The Quick Sort algorithm (Quick Sort) is an improvement of the bubble algorithm and is an unstable sort algorithm. The main idea is to divide the data to be sorted into two independent parts through a sorting, all the data in one part is smaller than all the data in the other part, and then the two parts of data are sorted quickly according to this method. The entire sorting process can be carried out recursively, and finally the entire data becomes an ordered sequence.

Bubble Sort is a simple sorting algorithm. It repeatedly traverses the sequence of numbers to be sorted, compares two elements at a time, and swaps them if they are in the wrong order. The work of traversing the sequence is repeated until no more exchanges are needed.
The operation of the bubble sort algorithm is as follows:
1. Compare adjacent elements. If the first one is greater than the second (ascending order), swap the two of them.
2. Do the same work for each pair of adjacent elements, from the first pair at the beginning to the last pair at the end. After this step is done, the last element will be the largest number.
3. Repeat the above steps for all elements except the last one.
4. Continue to repeat the above steps for fewer and fewer elements each time until there is no pair of numbers to compare.

2. Algorithm principle

  The quick sort algorithm works as follows:

  1. Pick an element from the sequence, called the pivot,
  2. Re-order the sequence, all elements smaller than the benchmark value are placed in front of the benchmark, and all elements larger than the benchmark value are placed behind the benchmark (the same number can go to either side). After the partition operation is over, the reference element is in its position after the final sorting.
  3. Recursively sort the sub-sequences of elements smaller than the reference value and the sub-sequences of elements greater than the reference value until there is only one element left in all the sub-sequences

3. Partition—partition

  Just master one of the following two methods

1. Digging method

Insert picture description here

At the beginning, there are pointers under 4 and 1, respectively, corresponding to the l and r pointers. The first pit is 4. Since the 1 pointed to by the r pointer is less than 4, 1 is moved to the pit pointed to by the l pointer, which is now 1 The source is a pit, the l pointer moves one bit to the right, pointing to 7, because the 7 pointed to by the l pointer is greater than 4, so 7 moves to the pit pointed to by the l pointer. At this time, the original 7 is a pit. Repeat the operation until the l pointer and r The pointers coincide, and the position is 4. The
partitioning operation is completed above,
and then recursively sort the sub-sequences of the element less than the reference value and the sub-sequences of the element greater than the reference value until there is only one sub-sequence left Element so far

2. Pointer exchange method

  The core idea is to find the pointers that do not meet the conditions on both sides and then exchange the pointers.
Insert picture description here

The benchmark is 4, the l pointer points to 7, the r pointer points to 1, because 1<4<7, the condition is not met, so the two pointers are exchanged, the r pointer moves by one bit, 1<4<8, when the condition is met, the r pointer moves by one Bit, 1<4<2 The right side does not meet the condition, the left side needs to be moved, the l pointer moves one bit, 6<4<2, both sides do not meet the conditions, the two pointers are exchanged, the r pointer moves one bit, 2<4<3 , The right side does not meet the condition, the l pointer moves one bit, 5<4<3, the two pointers are swapped, and the r pointer moves one bit to the left. At this time, the double pointers merge to point to 3, and 3 and 4 are swapped.
The above is the pointer exchange method.

4. How to choose benchmarks

  1. Select the first element as the benchmark
  2. Randomly select an element as a benchmark

5. Time complexity

  The average time complexity of quicksort is O(nlogn), and the worst-case time complexity is O(n^2).

When the first element is selected as the reference, n elements, each element is traversed once, at this time, the time complexity is O(n^2)

6.LeetCode

  215. Find the k-th largest element in the unsorted array (you need to find the k-th largest element after the array is sorted)

Input: [3,2,1,5,6,4] and k
output: 5

class Solution:
    def findKthElement(self, nums, k):
        '''
        找到数组中第k个最大元素,
        快速排序每一轮确定一个位置,如果我们想要的位置的元素确定了,那么排序就结束了
        :param nums: 数组
        :param k: k
        :return: 返回第k个最大元素
        '''
        return self.quickSort(nums, k)

    def quickSort(self, nums, k):
        # 找到我们要寻找元素的位置
        k = len(nums) - k
        # 左右指针的位置
        left, right = 0, len(nums) - 1  # 0,4
        while left < right:
            # 进行分区操作,得到确定的位置,将确定的位置与k进行比较后,对子数据集进行分区操作
            j = self.partition(nums, left, right)
            if j == k:
                break
            elif j < k:
                left = j + 1
            else:
                right = j - 1
        # 跳出循环有两个条件:一种是j=k,一种是left=right,两种情况下均可满足j=k
        return nums[k]

    def partition(self, nums, left, right):
        '''
        分区操作—挖坑法,确定某个元素的位置
        :param nums: 数组
        :param left: 左指针
        :param right: 右指针
        :return: 返回确定元素的位置
        '''
        pivot = nums[left]
        # quickSort函数中也有left、right函数
        i, j = left, right
        # 跳出循环的条件是:i = j,此时,即为元素的位置
        while i < j:
            # 跳出条件是找到小于基准的元素nums[j]或i=j
            while i < j and nums[j] > pivot:
                j -= 1
            if i < j:
                nums[i] = nums[j]
                i += 1

            # 找到大于基准的元素nums[i]
            while i < j and nums[i] <= pivot:
                i += 1
            if i < j:
                nums[j] = nums[i]
                j -= 1
        # i = j时
        nums[i] = pivot
        return i


def main():
    nums = [3, 2, 1, 5, 6, 4]
    k = 2
    s = Solution()
    kth_element = s.findKthElement(nums, k)
    print('数组中第%d个最大元素为%d' % (k, kth_element))


if __name__ == '__main__':
    main()

The code has been uploaded to https://github.com/Libra-1023/leetcode

Guess you like

Origin blog.csdn.net/weixin_46649052/article/details/114296843