【Leetcode】排序相关

【总结】

1.快排:

  选择一个点,该点左右元素互换使得左边都小于该点值、右边都大于该点值,当不需要换时返回。

  升序模板:

def quick_sort(arr, l, r):
    if l >= r:
        return
    item = arr[l]
    i, j = l, r
    while i < j:
        while arr[j] >= item and i < j: j -= 1
        if i < j: arr[i], arr[j] = arr[j], arr[i]
        while arr[i] <= item and i < j: i += 1
        if i < j: arr[i], arr[j] = arr[j], arr[i]
    quick_sort(arr, l, i - 1)
    quick_sort(arr, i + 1, r)

nums = [2, 3, 1, 5, 2, 3, 3, 8, 9, 1]
n = len(nums)
quick_sort(nums, 0, n - 1)

2.归并排序:

  选择中间位置,把中间位置的左右分别排好序,再把两段有序的合并起来

  升序排序模板:

def mergeSort(arr):
    def mergeList(left, right):
        res = []
        p1 = p2 = 0
        while p1 < len(left) or p2 < len(right):
            val1 = left[p1] if p1 < len(left) else float('inf')
            val2 = right[p2] if p2 < len(right) else float('inf')
            if val1 < val2:
                res.append(left[p1])
                p1 += 1
            else:
                res.append(right[p2])
                p2 += 1
        return res
    if len(arr) <= 1: return arr
    mid = len(arr) // 2
    left = mergeSort(arr[:mid])
    right = mergeSort(arr[mid:])
    return mergeList(left, right)
nums = [2, 3, 1, 5, 2, 3, 3, 8, 9, 1]
print(mergeSort(nums))

3.冒泡排序:

def sort1(nums):
    """
    冒泡排序:依次比较相邻,每次会把最大的浮到最后面
    """
    n = len(nums)
    for i in range(n):
        for j in range(n-1-i):
            if nums[j] > nums[j+1]:
                nums[j], nums[j+1] = nums[j+1], nums[j]
    return nums

4.插入排序:

def sort2(nums):
    """
    插入排序:把数字分别插入到已经排序好的数组中
    """
    n = len(nums)
    for i in range(1, n):  # 排第i个位置的元素, 从第二个元素开始计算插入位置
        item = nums[i]
        for j in reversed(range(i)):  # >nums[i]的元素后移
            if nums[j] > item:
                nums[j+1], nums[j] = nums[j], nums[j+1]
            else:
                break
    return nums

 

【Leetcode-23】

一、题目:合并k个升序链表

  给你一个链表数组,每个链表都已经按升序排列。

  请你将所有链表合并到一个升序链表中,返回合并后的链表。

二、代码:

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def mergeKLists(self, lists: List[Optional[ListNode]]) -> Optional[ListNode]:
        def mergeList(l1, l2):
            dummy = ListNode()
            p1, p2, p = l1, l2, dummy
            while p1 or p2:
                val1 = p1.val if p1 else float('inf')
                val2 = p2.val if p2 else float('inf')
                if val1 < val2:
                    p.next = p1
                    p1 = p1.next
                else:
                    p.next = p2
                    p2 = p2.next
                p = p.next
            return dummy.next
        n = len(lists)
        if n == 0: return None
        if n == 1: return lists[0] 
        mid = n // 2
        left = self.mergeKLists(lists[:mid])
        right = self.mergeKLists(lists[mid:])
        return mergeList(left, right)

 

【Leetcode-148】

一、题目:排序链表

  给你链表的头结点 head ,请将其按 升序 排列并返回 排序后的链表 。

  进阶:你可以在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序吗?

二、代码:

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def sortList(self, head: Optional[ListNode]) -> Optional[ListNode]:
        def splitList(head):
            if not head: return None, None
            if not head.next: return head, None
            p1, p2 = head, head.next
            while p2 and p2.next:
                p1 = p1.next
                p2 = p2.next.next
            p2 = p1.next
            p1.next = None
            return head, p2

        def mergeList(left, right):
            p = head = ListNode()
            p1, p2 = left, right
            while p1 or p2:
                val1 = p1.val if p1 else float('inf')
                val2 = p2.val if p2 else float('inf')
                if val1 < val2:
                    p.next = p1
                    p1 = p1.next
                else:
                    p.next = p2
                    p2 = p2.next
                p = p.next
            return head.next
            
        if not head or not head.next: return head
        left, right = splitList(head) # 拆成2段
        left = self.sortList(left) # 排两端
        right = self.sortList(right)
        res = mergeList(left, right) # 合并
        return res

 

【Leetcode-215】

一、题目:数组中的第k大元素

  在未排序的数组中找到第 k 个最大的元素。请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。

二、代码:

def findKthLargest(self, nums: List[int], k: int) -> int:
        def quicksort(arr, l, r):
            # if l >= r: return
            i, j = l, r
            item = arr[l]
            while i < j:
                while arr[j] <= item and i < j: j -= 1
                arr[i], arr[j] = arr[j], arr[i]
                while arr[i] >= item and i < j: i += 1
                arr[i], arr[j] = arr[j], arr[i]
            if k - 1 == i:  # k-1位置是第k大
                return arr[i]
            elif k - 1 < i:
                return quicksort(arr, l, i-1)
            else:
                return quicksort(arr, i+1, r)

        if len(nums) < k: return
        res = quicksort(nums, 0, len(nums) - 1)
        return res

 

【Leetcode-347】

一、题目:第k个高频元素

  给定一个非空的整数数组,返回其中出现频率前 高的元素。

二、代码:

def topKFrequent(self, nums: List[int], k: int) -> List[int]:
        """
        方法1:利用最小堆
        方法2:利用快排思想
        
        from collections import Counter
        count = Counter(nums)
        heap = []
        for num, cnt in count.items():
            if len(heap) < k:
                heapq.heappush(heap, (cnt, num))
            else:
                top = heap[0]  # 堆中最少的次数
                if top[0] < cnt:
                    heapq.heapreplace(heap, (cnt, num))
        res = [t[1] for t in heap]
        return res
        """
        def quick_sort(arr, l, r, k):
            # if l >= r:
            #     return
            item = arr[l][1]
            i, j = l, r
            while i < j:
                while arr[j][1] <= item and i < j:
                    j -= 1
                if i < j:
                    arr[i], arr[j] = arr[j], arr[i]
                while arr[i][1] >= item and i < j:
                    i += 1
                if i < j:
                    arr[i], arr[j] = arr[j], arr[i]
            if i == k-1:
                return arr[:k]
            elif i < k-1:
                return quick_sort(arr, i+1, r, k)
            else:
                return quick_sort(arr, l, i-1, k)

        from collections import Counter
        count = list(Counter(nums).items())
        n = len(count)
        res = quick_sort(count, 0, n - 1, k)
        return [t[0] for t in res]

 

posted @ 2021-04-01 22:56  我若成风者  阅读(54)  评论(0编辑  收藏  举报