CodeTop整理-排序篇

目录

补充题4. 手撕快速排序

148. 排序链表

目录

148. 排序链表

56. 合并区间

179. 最大数

补充题6. 手撕堆排序

补充题5. 手撕归并排序

164. 最大间距

75. 颜色分类

324. 摆动排序 II

面试题 16.16. 部分排序

452. 用最少数量的箭引爆气球

面试题 17.14. 最小K个数

315. 计算右侧小于当前元素的个数

1288. 删除被覆盖区间

1122. 数组的相对排序

剑指 Offer 45. 把数组排成最小的数

57. 插入区间

剑指 Offer 11. 旋转数组的最小数字

剑指 Offer 03. 数组中重复的数字


56. 合并区间

179. 最大数

补充题6. 手撕堆排序

补充题5. 手撕归并排序

164. 最大间距

75. 颜色分类

324. 摆动排序 II

面试题 16.16. 部分排序

452. 用最少数量的箭引爆气球

面试题 17.14. 最小K个数

315. 计算右侧小于当前元素的个数

1288. 删除被覆盖区间

1122. 数组的相对排序

剑指 Offer 45. 把数组排成最小的数

57. 插入区间


# 912. 排序数组
# 给你一个整数数组 nums,请你将该数组升序排列;手撕快排

# class Solution:
#     def randomized_partition(self, nums, l, r):
#         pivot = random.randint(l, r)
#         nums[pivot], nums[r] = nums[r], nums[pivot]
#         i = l - 1
#         for j in range(l, r):
#             if nums[j] < nums[r]:
#                 i += 1
#                 nums[j], nums[i] = nums[i], nums[j]
#         i += 1
#         nums[i], nums[r] = nums[r], nums[i]
#         return i
#
#     def randomized_quicksort(self, nums, l, r):
#         if r - l <= 0:
#             return
#         mid = self.randomized_partition(nums, l, r)
#         self.randomized_quicksort(nums, l, mid - 1)
#         self.randomized_quicksort(nums, mid + 1, r)
#
#     def sortArray(self, nums: List[int]) -> List[int]:
#         self.randomized_quicksort(nums, 0, len(nums) - 1)
#         return nums


class Solution:
    # def sortArray(self, nums: List[int]) -> List[int]:
    def sortArray(self, nums) :
        import random
        def find_povit(l,r):
            p=random.randint(l,r)
            t=nums[p]
            nums[p]=nums[l]
            nums[l]=t
            povit=nums[l]
            while (l<r):
                while l<r and povit<=nums[r]:    #这两个顺序反了,结果好像不一样了
                    r-=1
                nums[l]=nums[r]
                while l<r and povit>=nums[l]:
                    l+=1
                nums[r]=nums[l]
            nums[l]=povit
            return l

        def quick_sort(l,r):
            if(l>=r):
                return

            p=find_povit(l,r)
            quick_sort(l,p-1)
            quick_sort(p+1,r)

        quick_sort(0,len(nums)-1)
        return nums


nums=[2,4,6,8,1,3]
# nums=[5,2,3,1]
s=Solution()
r=s.sortArray(nums)
# r=s.quick_sort(nums)
print(r)
148. 排序链表
# 148. 排序链表
# 给你链表的头结点 head ,请将其按 升序 排列并返回 排序后的链表 。

# class Solution:
#     def sortList(self, head: ListNode) -> ListNode:
#         if not head or not head.next: return head # termination.
#         # cut the LinkedList at the mid index.
#         slow, fast = head, head.next
#         while fast and fast.next:
#             fast, slow = fast.next.next, slow.next
#         mid, slow.next = slow.next, None # save and cut.
#         # recursive for cutting.
#         left, right = self.sortList(head), self.sortList(mid)
#         # merge `left` and `right` linked list and return it.
#         h = res = ListNode(0)
#         while left and right:
#             if left.val < right.val: h.next, left = left, left.next
#             else: h.next, right = right, right.next
#             h = h.next
#         h.next = left if left else right
#         return res.next


# 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 sortList(self, head) :
        def merge_two(head1,head2):
            dumpy=ListNode(-1)
            newhead=dumpy
            while head1 and head2:
                if head1.val<head2.val:
                    cur=head1
                    head1=head1.next
                else:
                    cur=head2
                    head2=head2.next
                newhead.next=cur
                newhead=newhead.next
            if head1:
                newhead.next=head1
            if head2:
                newhead.next=head2
            return dumpy.next

        def merge_sort(h):
            if not h or not h.next:
                return h

            fast,slow=h.next,h
            while fast and fast.next:
                fast=fast.next.next
                slow=slow.next
            m=slow.next
            slow.next=None
            left=merge_sort(h)
            right=merge_sort(m)
            res=merge_two(left,right)
            return res

        ans=merge_sort(head)
        return ans
56. 合并区间
# 56. 合并区间
# 以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。请你合并所有重叠的区间,并返回一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间
# 输入:intervals = [[1,3],[2,6],[8,10],[15,18]]
# 输出:[[1,6],[8,10],[15,18]]
# 解释:区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].


class Solution:
    # def merge(self, intervals: List[List[int]]) -> List[List[int]]:
    def merge(self, intervals) :
        intervals.sort(key=lambda x:x[0])
        res=[intervals[0]]
        for i in range(1,len(intervals)):
            if res[-1][1]>=intervals[i][0]:
                res[-1][1]=max(res[-1][1],intervals[i][1])
            else:
                res.append(intervals[i])
        return res

intervals = [[1,3],[2,6],[8,10],[15,18]]
s=Solution()
r=s.merge(intervals)
print(r)

179. 最大数
# 179. 最大数
# 给定一组非负整数 nums,重新排列每个数的顺序(每个数不可拆分)使之组成一个最大的整数。
# 注意:输出结果可能非常大,所以你需要返回一个字符串而不是整数。

# 输入:nums = [3,30,34,5,9]
# 输出:"9534330"

class Solution:
    # def largestNumber(self, nums: List[int]) -> str:
    def largestNumber(self, nums) :
        nums=list(map(str,nums))
        for i in range(len(nums)):
            for j in range(i+1,len(nums)):
                if(nums[i]+nums[j]<nums[j]+nums[i]):
                    nums[i],nums[j]=nums[j],nums[i]
        s=''.join(nums)
        if s.startswith('0'):
            return '0'
        return s


nums = [3,30,34,5,9]
s=Solution()
r=s.largestNumber(nums)
print(r)
补充题6. 手撕堆排序
# 912. 排序数组
# 给你一个整数数组 nums,请你将该数组升序排列;手撕快排

class Solution:
    # def sortArray(self, nums: List[int]) -> List[int]:
    def sortArray(self, nums) :
        def adjust(i,n):
            l,r=2*i+1,2*i+2
            largest=i
            if (l<n and nums[l]>nums[largest]):
                largest=l
            if(r<n and nums[r]>nums[largest]):
                largest=r
            if largest!=i :
                nums[largest],nums[i]=nums[i],nums[largest]
                adjust(largest,n)


                adjust(largest,n)
        def heap_sort():
            for i in range((len(nums))//2,-1,-1):
                adjust(i,len(nums))
            for i in range(len(nums)):
                nums[0],nums[len(nums)-1-i]=nums[len(nums)-1-i],nums[0]
                adjust(0,len(nums)-i-1)

        heap_sort()
        return nums


nums=[2,4,6,8,1,3]
# nums=[5,2,3,1]
s=Solution()
r=s.sortArray(nums)
# r=s.quick_sort(nums)
print(r)
补充题5. 手撕归并排序
# 912. 排序数组
# 给你一个整数数组 nums,请你将该数组升序排列;手撕快排

class Solution:
    # def sortArray(self, nums: List[int]) -> List[int]:
    def sortArray(self, nums) :
        def merge(l,m,r):
            a=[]
            i,j=l,m+1
            while i<=m and j<=r:
                if(nums[i]>nums[j]):
                    a.append(nums[j])
                    j+=1
                else:
                    a.append(nums[i])
                    i+=1
            while i<=m:
                a.append(nums[i])
                i+=1
            while j<=r:
                a.append(nums[j])
                j+=1
            p=0
            for k in range(l,r+1):
                nums[k]=a[p]
                p+=1


        def merge_sort(l,r):
            if l>=r:
                return
            m=(l+r)//2
            merge_sort(l,m)
            merge_sort(m+1,r)
            merge(l,m,r)

        l,r=0,len(nums)-1
        merge_sort(l,r)
        return nums


# nums=[2,4,6,8,1,3]
# nums=[5,2,3,1]
nums=[-2,3,-5]
s=Solution()
r=s.sortArray(nums)
# r=s.quick_sort(nums)
print(r)
164. 最大间距
# 164. 最大间距
# 给定一个无序的数组nums,返回 数组在排序之后,相邻元素之间最大的差值 。如果数组元素个数小于 2,则返回 0 。
# 您必须编写一个在「线性时间」内运行并使用「线性额外空间」的算法。
# 输入: nums = [3,6,9,1]
# 输出: 3
# 解释: 排序后的数组是 [1,3,6,9], 其中相邻元素 (3,6) 和 (6,9) 之间都存在最大差值 3。
#
# 提示:
#
# 1 <= nums.length <= 105
# 0 <= nums[i] <= 109


# class Solution:
#     def maximumGap(self, nums: List[int]) -> int:
#         if len(nums) < 2: return 0
#
#         # 一些初始化
#         max_ = max(nums)
#         min_ = min(nums)
#         max_gap = 0
#
#         each_bucket_len = max(1,(max_-min_) // (len(nums)-1))
#         buckets =[[] for _ in range((max_-min_) // each_bucket_len + 1)]
#
#         # 把数字放入桶中
#         for i in range(len(nums)):
#             loc = (nums[i] - min_) // each_bucket_len
#             buckets[loc].append(nums[i])
#
#         # 遍历桶更新答案
#         prev_max = float('inf')
#         for i in range(len(buckets)):
#             if buckets[i] and prev_max != float('inf'):
#                 max_gap = max(max_gap, min(buckets[i])-prev_max)
#
#             if buckets[i]:
#                 prev_max = max(buckets[i])
#
#         return max_gap
#
class Solution:
    # def maximumGap(self, nums: List[int]) -> int:
    def maximumGap(self, nums):
        if len(nums)<2:
            return 0
        max_,min_=max(nums),min(nums)
        bucket_len=max((max_-min_)//(len(nums)-1),1)     #等差数列、max_gap
        bucket_cnt=(max_-min_)//bucket_len+1        #从min_到max_计数排序

        buckets=[[float('inf'),float('-inf')] for i in range(bucket_cnt)]

        for num in nums:
            i=(num-min_)//bucket_len
            buckets[i][0]=min(buckets[i][0],num)
            buckets[i][1]=max(buckets[i][1],num)
        pre_i=-1
        ans=0
        for i in range(bucket_cnt):
            if buckets[i][0]>buckets[i][1]:
                continue
            if pre_i!=-1 :
                ans=max(buckets[i][0]-buckets[pre_i][1],ans)
            pre_i=i
        return ans

# nums = [3,6,9,1]
nums=[1,10000000]
s=Solution()
r=s.maximumGap(nums)
print(r)
75. 颜色分类
# 75. 颜色分类
# 给定一个包含红色、白色和蓝色、共 n 个元素的数组 nums ,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。
#
# 我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。
#
# 必须在不使用库的sort函数的情况下解决这个问题
# 给定一个包含红色、白色和蓝色、共 n 个元素的数组 nums ,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。
#
# 我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。
#
# 必须在不使用库的sort函数的情况下解决这个问题

# 输入:nums = [2,0,2,1,1,0]
# 输出:[0,0,1,1,2,2]


from typing import List

class Solution:
    def sortColors(self, nums: List[int]) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """
        h=[0]*3
        for num in nums:
            h[num]+=1

        k=0
        for i in range(3):
            for j in range(h[i]):
                nums[k]=i
                k+=1
nums = [2,0,2,1,1,0]
s=Solution()
s.sortColors(nums)
print(nums)

324. 摆动排序 II
# 324. 摆动排序 II
# 给你一个整数数组 nums,将它重新排列成 nums[0] < nums[1] > nums[2] < nums[3]... 的顺序。
#
# 你可以假设所有输入数组都可以得到满足题目要求的结果。
#
# 输入:nums = [1,5,1,1,6,4]
# 输出:[1,6,1,5,1,4]
# 解释:[1,4,1,5,1,6] 同样是符合题目要求的结果,可以被判题程序接受。


from typing import List
# class Solution:
#     def wiggleSort(self, nums: List[int]) -> None:
#         """
#         Do not return anything, modify nums in-place instead.
#         """
#         if len(nums)<2:
#             return
#
#         i=1
#         while  i<len(nums) :
#             l,k,r=i-1,i,min(i+1,len(nums)-1)   #类似于堆排序;这里是奇数位的数值和左右两边比较,并将最左右两边比nums[i]大的进行交换,处理不了存在连续相等数的情况
#             max_=max(nums[l],nums[r])
#             if(max_>nums[k]):
#                 if nums[l]<nums[r]:
#                     k=r
#                 else:
#                     k=l
#             if k!=i:
#                 nums[k],nums[i]=nums[i],nums[k]
#             i+=2


# 比较好想到的方法,先排序,再依次插入

# class Solution:
#     def wiggleSort(self, nums: List[int]) -> None:
#         n = len(nums)
#         arr = sorted(nums)
#         x = (n + 1) // 2
#         j, k = x - 1, n - 1
#         for i in range(0, n, 2):
#             nums[i] = arr[j]
#             if i + 1 < n:
#                 nums[i + 1] = arr[k]
#             j -= 1
#             k -= 1

class Solution:
    def wiggleSort(self, nums: List[int]) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """
        if len(nums)<2:
            return

        a=sorted(nums)
        l,r=(len(nums)+1)//2-1,len(nums)-1    #避免中间有一串相等的数

        for i in range(len(nums)):
            print(i,l,r)
            if(i%2==0):
                nums[i]=a[l]      #交换把数据弄没了,直接给数据赋值
                l-=1
            else:
                nums[i]=a[r]
                r-=1

nums = [1,5,1,1,6,4]
# nums=[5,5,5,4,4,4,4]
# nums=[1,1,2,1,2,2,1]    #[1,2,1,2,1,2,1]

s=Solution()
s.wiggleSort(nums)

面试题 16.16. 部分排序
# 面试题 16.16. 部分排序
# 给定一个整数数组,编写一个函数,找出索引m和n,只要将索引区间[m,n]的元素排好序,整个数组就是有序的。注意:n-m尽量最小,也就是说,找出符合条件的最短序列。函数返回值为[m,n],若不存在这样的m和n(例如整个数组是有序的),请返回[-1,-1]。
# 输入: [1,2,4,7,10,11,7,12,6,7,16,18,19]
# 输出: [3,9]

from typing import List
class Solution:
    def subSort(self, array: List[int]) -> List[int]:
        if len(array)<2:
            return [-1,-1]
        l,r=1,len(array)-1

        while(l<len(array) and array[l-1]<=array[l]):
            l+=1
        if(l==len(array)):
            return [-1,-1]
        while(array[r]>array[l-1] and array[r]>=array[r-1] ):
            r-=1
        # print(l-1,r+1)
        l,r=l-1,r+1    #满足条件的节点为[0,l-1],[r+1,len(array)-1]
        min_i,max_i = l+1,r-1
        for i in range(l , r):
            if (array[min_i] >= array[i]):
                min_i = i
            if (array[max_i] <= array[i]):
                max_i = i
        # print('&',array[min_i],array[max_i],'#',min_i,max_i,l,r)
        while(r<len(array) and  array[max_i]>array[r]):
            r+=1
        while(l>=0 and array[min_i]<array[l]):
            l-=1
        return [l+1,r-1]



a=[1,2,4,7,10,11,7,12,6,7,16,18,19]
# a=[1,3,5,7,9]
print(len(a))
s=Solution()
r=s.subSort(a)
print(r)

452. 用最少数量的箭引爆气球
# 452. 用最少数量的箭引爆气球
# 有一些球形气球贴在一堵用 XY 平面表示的墙面上。墙面上的气球记录在整数数组points,其中points[i] = [xstart, xend]表示水平直径在xstart和xend之间的气球。你不知道气球的确切 y 坐标。
#
# 一支弓箭可以沿着 x 轴从不同点 完全垂直 地射出。在坐标 x 处射出一支箭,若有一个气球的直径的开始和结束坐标为 xstart,xend, 且满足 xstart≤ x ≤ xend,则该气球会被 引爆。可以射出的弓箭的数量 没有限制 。 弓箭一旦被射出之后,可以无限地前进。
#
# 给你一个数组 points ,返回引爆所有气球所必须射出的 最小 弓箭数。
#
# 输入:points = [[10,16],[2,8],[1,6],[7,12]]
# 输出:2
# 解释:气球可以用2支箭来爆破:
# -在x = 6处射出箭,击破气球[2,8]和[1,6]。
# -在x = 11处发射箭,击破气球[10,16]和[7,12]。

from typing import List
class Solution:
    def findMinArrowShots(self, points: List[List[int]]) -> int:
        if not points:
            return 0
        points.sort(key=lambda x:x[0])
        res=[points[0]]
        for i ,t in enumerate(points):
            if res[-1][1]>=points[i][0]:
                res[-1][1]=min(res[-1][1],points[i][1])
            else:
                res.append(points[i])
        # print(res)
        return len(res)


# points = [[10,16],[2,8],[1,6],[7,12]]
points = [[1,2],[2,3],[3,4],[4,5]]
s=Solution()
r=s.findMinArrowShots(points)
print(r)
面试题 17.14. 最小K个数
 面试题 17.14. 最小K个数
# 设计一个算法,找出数组中最小的k个数。以任意顺序返回这k个数均可。
# 输入: arr = [1,3,5,7,2,4,6,8], k = 4
# 输出: [1,2,3,4]

from  typing  import List
class Solution:
    def smallestK(self, arr: List[int], k: int) -> List[int]:
        def find_pivot(l,r):
            p=arr[l]
            while(l<r):
                while(l<r and arr[r]>=p):
                    r-=1
                if(l<r):
                    arr[l]=arr[r]
                while(l<r and arr[l]<=p):
                    l+=1
                if(l<r):
                    arr[r]=arr[l]
            arr[l]=p
            return l

        l,r=0,len(arr)-1
        while(l<=r):
            p=find_pivot(l,r)
            if(k-1==p):
                break
            elif(k-1<p):
                r=p-1
            else:
                l=p+1
        print(arr)
        return arr[0:k]

arr = [1,3,5,7,2,4,6,8]
k = 4
s=Solution()
r=s.smallestK(arr,k)
print(r)
315. 计算右侧小于当前元素的个数
# 315. 计算右侧小于当前元素的个数
# 给你一个整数数组 nums ,按要求返回一个新数组counts 。数组 counts 有该性质: counts[i] 的值是 nums[i] 右侧小于nums[i] 的元素的数量。
# 输入:nums = [5,2,6,1]
# 输出:[2,1,1,0]
# 解释:
# 5 的右侧有 2 个更小的元素 (2 和 1)
# 2 的右侧仅有 1 个更小的元素 (1)
# 6 的右侧有 1 个更小的元素 (1)
# 1 的右侧有 0 个更小的元素
# https://leetcode.cn/problems/count-of-smaller-numbers-after-self/solution/4chong-jie-fa-yi-wang-da-jin-pai-xu-shu-5vvds/

from typing import List
# 最直观的解法,n^2的时间复杂度,超时
# class Solution:
#     def countSmaller(self, nums: List[int]) -> List[int]:
#         if len(nums)<1:
#             return [0]
#         ans=[0]*len(nums)
#         for i in range(len(nums)-2,-1,-1):
#             j,k=i,i+1
#             while(k<len(nums)):
#                 if(nums[j]>nums[k]):
#                     ans[i]=ans[k]+1
#                 k+=1
#         return ans

# 归并排序求逆序对,直接用字典存储,无法解析存在相同数值的下标
# class Solution:
#     def countSmaller(self, nums: List[int]) -> List[int]:
#         if len(nums)<=1:
#             return [0]
#         ans=[0]*len(nums)
#         h={}
#         for i in range(len(nums)):
#             h[nums[i]]=i
#
#         def merge(l,m,r):
#             i,j,k=l,m+1,0
#             t=[]
#             while i<=m and j<=r:
#                 if nums[i]<=nums[j]:
#                     ans[h[nums[i]]]+=j-(m+1)
#                     t.append(nums[i])
#                     i+=1
#                 else:
#                     t.append(nums[j])
#                     j+=1
#             while i<=m:
#                 t.append(nums[i])
#                 ans[h[nums[i]]] += j-(m+1)
#                 i+=1
#             while j<=r:
#                 t.append(nums[j])
#                 j+=1
#             for i in range(l,r+1):
#                 nums[i]=t[k]
#                 k+=1
#
#         def merge_sort(l,r):
#             if(l>=r):
#                 return
#             m=(l+r)//2
#             merge_sort(l,m)
#             merge_sort(m+1,r)
#             merge(l,m,r)
#         l,r=0,len(nums)-1
#         merge_sort(l,r)
#         return ans


# 与上面的方法类似,index记录索引(可变),tmpindex记录交换了的索引,这个方法运行能通过,也是官网解法
class Solution:
    def countSmaller(self, nums: List[int]) -> List[int]:
        if len(nums)<=1:
            return [0]
        ans=[0]*len(nums)
        index=[]
        for i in range(len(nums)):
            index.append(i)

        def merge(l,m,r):
            i,j,k=l,m+1,0
            t=[]
            tmpindex=[]
            while i<=m and j<=r:
                if nums[i]<=nums[j]:
                    ans[index[i]]+=j-(m+1)
                    t.append(nums[i])
                    tmpindex.append(index[i])
                    i+=1
                else:
                    t.append(nums[j])
                    tmpindex.append(index[j])
                    j+=1
            while i<=m:
                t.append(nums[i])
                tmpindex.append(index[i])
                ans[index[i]] += j-(m+1)
                i+=1
            while j<=r:
                t.append(nums[j])
                tmpindex.append(index[j])
                j+=1
            for i in range(l,r+1):
                nums[i]=t[k]
                index[i] =tmpindex[k]
                k+=1

        def merge_sort(l,r):
            if(l>=r):
                return
            m=(l+r)//2
            merge_sort(l,m)
            merge_sort(m+1,r)
            merge(l,m,r)
        l,r=0,len(nums)-1
        merge_sort(l,r)
        return ans
1288. 删除被覆盖区间
# 1288. 删除被覆盖区间
# 给你一个区间列表,请你删除列表中被其他区间所覆盖的区间。
# 只有当c <= a且b <= d时,我们才认为区间[a,b) 被区间[c,d) 覆盖。
# 在完成所有删除操作后,请你返回列表中剩余区间的数目。
# 输入:intervals = [[1,4],[3,6],[2,8]]
# 输出:2
# 解释:区间 [3,6] 被区间 [2,8] 覆盖,所以它被删除了。

from typing import List
class Solution:
    def removeCoveredIntervals(self, intervals: List[List[int]]) -> int:
        intervals.sort(key=lambda x:x[0])
        res=[intervals[0]]
        for i in range(len(intervals)):
            if res[-1][1]>=intervals[i][1]:
                continue
            elif res[-1][1]<=intervals[i][1] and res[-1][0]==intervals[i][0]:
                res[-1][1]=max(res[-1][1],intervals[i][1])
            else:
                res.append(intervals[i])
        ans=len(res)

        return ans

# intervals = [[1,4],[3,6],[2,8]]
intervals =[[1,2],[1,4],[3,4]]
s=Solution()
r=s.removeCoveredIntervals(intervals)
print(r)
1122. 数组的相对排序
# 1122. 数组的相对排序
# 给你两个数组,arr1 和arr2,arr2中的元素各不相同,arr2 中的每个元素都出现在arr1中。
# 对 arr1中的元素进行排序,使 arr1 中项的相对顺序和arr2中的相对顺序相同。未在arr2中出现过的元素需要按照升序放在arr1的末尾。
# 输入: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]

from typing import List
class Solution:
    def relativeSortArray(self, arr1: List[int], arr2: List[int]) -> List[int]:
        h,t={},[]
        for num in arr2:
            h[num]=0
        for i in range(len(arr1)-1,-1,-1):
            if arr1[i] in h:
                h[arr1[i]]+=1
            else:
                t.append(arr1[i])

        p=0
        for num in arr2:
            for q in range(h[num]):
                arr1[p]=num
                p+=1
        t.sort()
        for num in t:
            arr1[p]=num
            p+=1
        return arr1

arr1 = [2,3,1,3,2,4,6,7,9,2,19]
arr2 = [2,1,4,3,9,6]
s=Solution()
r=s.relativeSortArray(arr1,arr2)
print(r)
剑指 Offer 45. 把数组排成最小的数
# 剑指 Offer 45. 把数组排成最小的数
# 输入一个非负整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。
# 输入: [10,2]
# 输出: "102"

from typing import List
class Solution:
    def minNumber(self, nums: List[int]) -> str:
        if not nums:
            return ''
        a=list(map(str,nums))
        for i in range(len(a)):
            for j in range(i+1,len(a)):
                if(a[i]+a[j]>=a[j]+a[i]):
                    a[i],a[j]=a[j],a[i]
        return ''.join(a)
a=[10,2]
a=[3,30,34,5,9]
s=Solution()
r=s.minNumber(a)
print(r)
57. 插入区间
# 57. 插入区间
# 给你一个 无重叠的 ,按照区间起始端点排序的区间列表。
# 在列表中插入一个新的区间,你需要确保列表中的区间仍然有序且不重叠(如果有必要的话,可以合并区间)
# 输入:intervals = [[1,3],[6,9]], newInterval = [2,5]
# 输出:[[1,5],[6,9]]

from typing import List
class Solution:
    def insert(self, intervals: List[List[int]], newInterval: List[int]) -> List[List[int]]:
        intervals.append(newInterval)
        if len(intervals)<=1:
            return intervals
        intervals.sort(key=lambda x:x[0])
        res=[intervals[0]]
        for i in range(len(intervals)):
            if res[-1][1]>=intervals[i][0]:
                res[-1][1]=max(res[-1][1],intervals[i][1])
            else:
                res.append(intervals[i])
        return res
剑指 Offer 11. 旋转数组的最小数字
class Solution:
    def minArray(self, numbers: List[int]) -> int:
        l,r=0,len(numbers)-1
        while(l<r):
            m=(l+r)//2
            if(numbers[m]<numbers[r]):
                r=m
            elif(numbers[m]>numbers[r]):
                l=m+1
            else: #去掉重复元素
                r-=1
        return numbers[l]
剑指 Offer 03. 数组中重复的数字
class Solution:
    def findRepeatNumber(self, nums: List[int]) -> int:
        i=0
        while(i<len(nums)):
            if(nums[i]==i):     #第一次出现,i+1
                i=i+1
                continue
            if(nums[nums[i]]==nums[i]):  #nums[i]位置已有元素nums[i]
                return nums[i]
            nums[nums[i]],nums[i]=nums[i],nums[nums[i]]   #将nums[nums[i]]=nums[i],将nums[i]放到nums[i]的位置
            # print(i,nums)
        
            


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值