LeetCode刷题——排序(python语言)

LeetCode刷题——排序(python语言)

一、排序

顾名思义,排序就是将数组按照从小到大的顺序排列。
广义的排序分为内部排序方法和外部排序方法。
排序的方法有很多种,常用的冒泡、选择、插入、希尔、归并、快速、堆、计数、桶、基数排序。
按照时间复杂度划分:
O ( n 2 ) O(n^2) O(n2):冒泡、选择、插入
O ( n ∗ l o g 2 n ) O(n*log_2n) O(nlog2n) :希尔、归并、快速、堆
O ( n ) O(n) O(n):计数、桶、基数

二、刷题

2.1 排序数组

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

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

示例 2:
输入:nums = [5,1,1,2,0,0]
输出:[0,0,1,1,2,5]

提示:
1 <= nums.length <= 5 * 104
-5 * 104 <= nums[i] <= 5 * 104
解法1:调用sort函数

class Solution:
    def sortArray(self, nums: List[int]) -> List[int]:
        nums.sort()
        return nums

解法2:快速排序

class Solution:
    def randomPartition(self,arr:[int],low:int,high:int):
        i = random.randint(low,high)
        arr[i],arr[high]=arr[high],arr[i]
        return self.partition(arr,low,high)
    def partition(self,arr:[int],low:int,high:int):
        i = low -1 
        pivot = arr[high]
        for j in range(low,high):
            if (arr[j]<= pivot):
                i+= 1 
                arr[i],arr[j]=arr[j],arr[i]
        arr[i+1],arr[high] = arr[high],arr[i+1]
        return i + 1 
    def quicksort(self,arr,low,high):
        if low<high:
            pi = self.randomPartition(arr,low,high)
            self.quicksort(arr,low,pi-1)
            self.quicksort(arr,pi+1,high)
        return arr 
    def sortArray(self, nums: List[int]) -> List[int]:
        return self.quicksort(nums,0,len(nums)-1)

2.2 合并两个有序数组

给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。
请你 合并 nums2 到 nums1 中,使合并后的数组同样按 非递减顺序 排列。
注意:最终,合并后数组不应由函数返回,而是存储在数组 nums1 中。为了应对这种情况,nums1 的初始长度为 m + n,其中前 m 个元素表示应合并的元素,后 n 个元素为 0 ,应忽略。nums2 的长度为 n 。

示例 1:
输入:nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3
输出:[1,2,2,3,5,6]
解释:需要合并 [1,2,3] 和 [2,5,6] 。
合并结果是 [1,2,2,3,5,6] ,其中斜体加粗标注的为 nums1 中的元素。

示例 2:
输入:nums1 = [1], m = 1, nums2 = [], n = 0
输出:[1]
解释:需要合并 [1] 和 [] 。
合并结果是 [1] 。

示例 3:
输入:nums1 = [0], m = 0, nums2 = [1], n = 1
输出:[1]
解释:需要合并的数组是 [] 和 [1] 。
合并结果是 [1] 。
注意,因为 m = 0 ,所以 nums1 中没有元素。nums1 中仅存的 0 仅仅是为了确保合并结果可以顺利存放到 nums1 中。

提示:
nums1.length == m + n
nums2.length == n
0 <= m, n <= 200
1 <= m + n <= 200
-109 <= nums1[i], nums2[j] <= 109

进阶:你可以设计实现一个时间复杂度为 O(m + n) 的算法解决此问题吗?
**解法:**对第二个数组讨论,加入第一个数组,然后排序

class Solution:
    def merge(self, nums1: List[int], m: int, nums2: List[int], n: int) -> None:
        """
        Do not return anything, modify nums1 in-place instead.
        """
        
        if(len(nums2)==0):
            return 
        count = 0
        for i in range(m,m+n):
            nums1[i] = nums2[count]
            count += 1
        nums1.sort()
        

2.3 有序数组的平方

给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。

示例 1:
输入:nums = [-4,-1,0,3,10]
输出:[0,1,9,16,100]
解释:平方后,数组变为 [16,1,0,9,100]
排序后,数组变为 [0,1,9,16,100]

示例 2:
输入:nums = [-7,-3,2,3,11]
输出:[4,9,9,49,121]

提示:
1 <= nums.length <= 104
-104 <= nums[i] <= 104
nums 已按 非递减顺序 排序

进阶:

请你设计时间复杂度为 O(n) 的算法解决本问题
解法1:先排序,再平方


class Solution:
    def sortedSquares(self, nums: List[int]) -> List[int]:
        new_nums = sorted(nums,key=lambda x:x**2)
        ans = list(map(lambda x:x**2,new_nums))
        return ans

解法2:先平方,再排序


class Solution:
    def sortedSquares(self, nums: List[int]) -> List[int]:
        ans = list(map(lambda x:x**2,nums))
        ans.sort()
        return ans

2.4 数组的相对排序

给你两个数组,arr1 和 arr2,arr2 中的元素各不相同,arr2 中的每个元素都出现在 arr1 中。

对 arr1 中的元素进行排序,使 arr1 中项的相对顺序和 arr2 中的相对顺序相同。未在 arr2 中出现过的元素需要按照升序放在 arr1 的末尾。

示例 1:
输入:arr1 = [2,3,1,3,2,4,6,7,9,2,19], arr2 = [2,1,4,3,9,6]
输出:[2,2,2,1,4,3,3,9,6,7,19]

示例 2:
输入:arr1 = [28,6,22,8,44,17], arr2 = [22,28,8,6]
输出:[22,28,8,6,17,44]

提示:
1 <= arr1.length, arr2.length <= 1000
0 <= arr1[i], arr2[i] <= 1000
arr2 中的元素 arr2[i] 各不相同
arr2 中的每个元素 arr2[i] 都出现在 arr1 中
**解法:**设置第三个是数组,按照第二个数组查找, 然后第一个数组删除,最后加入第一个数组中的剩余元素

class Solution:
    def relativeSortArray(self, arr1: List[int], arr2: List[int]) -> List[int]:
        arr3 = []
        for num in arr2:
            while(num in arr1):
                arr3.append(num)
                arr1.remove(num)
        arr1.sort()
        for num in arr1:
            arr3.append(num)
        return arr3

2.5 对链表进行插入排

给定单个链表的头 head ,使用 插入排序 对链表进行排序,并返回 排序后链表的头 。

插入排序 算法的步骤:
插入排序是迭代的,每次只移动一个元素,直到所有元素可以形成一个有序的输出列表。
每次迭代中,插入排序只从输入数据中移除一个待排序的元素,找到它在序列中适当的位置,并将其插入。
重复直到所有输入数据插入完为止。
下面是插入排序算法的一个图形示例。部分排序的列表(黑色)最初只包含列表中的第一个元素。每次迭代时,从输入数据中删除一个元素(红色),并就地插入已排序的列表中。
在这里插入图片描述

对链表进行插入排序。
示例 1:
输入: head = [4,2,1,3]
输出: [1,2,3,4]
在这里插入图片描述
示例 2:

输入: head = [-1,5,3,4,0]
输出: [-1,0,3,4,5]
在这里插入图片描述

提示:

列表中的节点数在 [1, 5000]范围内
-5000 <= Node.val <= 5000
**解法:**根据链表的特点,构建链表,然后插入排序,注意空链表和一个节点的链表情况

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def insertionSortList(self, head: ListNode) -> ListNode:
        if not head:
            return head
        # 用于链接新列表
        new_head = ListNode(0)
        # cur 用于拿出元素
        cur = head
        # 对原列表进行排序
        while cur:
            # 标志位,标志是否遍历到new_head最后,还没把cur插入进去
            target = 0 
            # 每次插入new_head都要从头开始
            temp_head = new_head
            # 将新值插入new_head
            while temp_head.next:
                # 如果下一个为空则直接链接cur
                if  temp_head.next.val >= cur.val:
                    # 将temp_head下一个变成cur
                    next_next = temp_head.next 
                    temp_head.next = cur
                    cur = cur.next
                    temp_head.next.next = next_next
                    target = 1 
                    break 
                    # temp_head下一个已经是变成cur,但是后面要接上temp_head.next(cur).next
                temp_head = temp_head.next
            if target == 0:
                temp_head.next = cur
                cur = cur.next
                temp_head.next.next = None


        return new_head.next
        
                
            
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值