python算法日记(归并排序)_leetcode 148. 排序链表 912. 排序数组

912. 排序数组

给定一个整数数组 nums,将该数组升序排列。

示例 1:

输入:[5,2,3,1]
输出:[1,2,3,5]
示例 2:

输入:[5,1,1,2,0,0]
输出:[0,0,1,1,2,5]

提示:

1 <= A.length <= 10000
-50000 <= A[i] <= 50000

来源:力扣(LeetCode)链接:https://leetcode-cn.com/problems/sort-list

用归并排序的方法来做:

class Solution:
    def sortArray(self, nums: List[int]) -> List[int]:
        if len(nums)==1:  #递归边界:数组长度为1时返回
            return nums
        mid = len(nums)//2  #递归一直分成两半,直到分成左右(1,1),或左右(1,2)or(2,1),则1的直接返回,2的再分成(1,1)
        pre = nums[:mid]
        tail= nums[mid:]
        left = self.sortArray(pre)
        right = self.sortArray(tail)
        res = [] #用于装合并后的有序数组
        while left and right:  # 合并,左右(1,1)合并时,把小的装进去,大的由下面if装 
            if left[0]<=right[0]:
                res.append(left.pop(0)) #left,right长大于1时,注意从第一个开始比
            else:
                res.append(right.pop(0)) #注意装完要轮空,不然会死循环
        if left:    #用来处理while后剩下的一个
            res+=left
        if right:
            res+=right
        return res

归并的思想,先一直分成两半,再排序合并起来。代码中通过while以下部分合并

示例2过程:

       [5,1,1,2,0,0]

分  [5,1,1]   [2,0,0]

分 [5] [1,1] [2] [0,0]

分 [5]  [1][1]  [2]  [0][0]

合       [1,1]        [0,0]          # [1,1]返回给right和left[5]一起进入while,right[0,0]和left[2]同理

合 [1,1,5]       [0,0,2]

合    [0,0,1,1,2,5]

也可以把合并单独写成一个函数:

class Solution:
    def sortArray(self, nums: List[int]) -> List[int]:
        def marge(left, right):
            res = []
            while left and right:
            # 左右两个数列第一个最小放前面
                if left[0] <= right[0]:
                    res.append(left.pop(0))
                else:
                    res.append(right.pop(0))
            # 只有一个数列中还有值,直接添加
            res += left
            res += right
            return res
        if len(nums) == 1: 
            return nums
        mid = len(nums) // 2
        left = nums[:mid]
        right = nums[mid:]
        return marge(self.sortArray(left), self.sortArray(right))

 有了912题的经验,148就比较容易了:

148. 排序链表

在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序。

示例 1:

输入: 4->2->1->3
输出: 1->2->3->4
示例 2:

输入: -1->5->3->4->0
输出: -1->0->3->4->5

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def sortList(self, head: ListNode) -> ListNode:
        if not head or not head.next: # 链表为空的情况直接返回not head.next类似于数组长度为1
            return head
        slow = head      #用快慢指针把链表分成两半
        fast = head.next
        while(fast and fast.next):
            slow = slow.next
            fast = fast.next.next
        tmp = slow.next
        slow.next = None  #把前半部分的尾巴置空
        left = self.sortList(head)
        right = self.sortList(tmp)
        cur =  res = ListNode(0)  #用一个新链表装排序后合并的部分
        while left and right:
            if left.val<=right.val:
                cur.next = left
                left = left.next #加入后置空或用下一位进入比较
            else:
                cur.next = right
                right = right.next
            cur = cur.next
        cur.next = left or right  #把while过后剩下的接上去
        return res.next

示例二过程:

       -1->5->3->4->0

分  -1->5        3->4->0

分  -1   5        3    4->0

分 -1   5         3    4   0

合 -1->5         3   0->4

合 -1->5         0->3->4

合  -1->0->3->4->5

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值