LeetCode组队学习task3练习题

剑指offer45.把数组排成最小的数

输入一个非负整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。

提示有写:输出结果可能非常大,所以你需要返回一个字符串而不是整数

我们可以利用拼接字符串来完成最后输出。

class Solution:
    def minNumber(self, nums: List[int]) -> str:
        def com(x,y):
            a,b = x+y,y+x
            if a > b :
                return 1
            elif a < b :
                return -1
            else:
                return 0
        strs = [str(num) for num in nums]
        strs.sort(key = functools.cmp_to_key(com))
        return ''.join(strs)

使用内置sort函数,设置sort rule来对所求str进行筛选。

283.移动零

给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。

class Solution:
    def moveZeroes(self, nums: List[int]) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """
        n = len(nums)
        i = j = 0
        while j < n:
            if nums[j] != 0:
                nums[i],nums[j] = nums[j],nums[i]
                i +=1
            j += 1
        return nums

选出0项向右移。

912.排序数组

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

506.相对名次

给你一个长度为 n 的整数数组 score ,其中 score[i] 是第 i 位运动员在比赛中的得分。

class Solution:
    desc = ("Gold Medal", "Silver Medal", "Bronze Medal")
    def findRelativeRanks(self, score: List[int]) -> List[str]:
        ans = [""] * len(score)
        arr = sorted(enumerate(score), key=lambda x: -x[1])
        for i, (idx, _) in enumerate(arr):
            ans[idx] = self.desc[i] if i < 3 else str(i + 1)
        return ans

88.合并两个有序数组

给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。请你合并 nums2 到 nums1 中,使合并后的数组同样按 非递减顺序 排列。

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.
        """
        nums1[m:] = nums2
        nums1.sort()

剑指offer51.数组中的逆序对

在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。

75.颜色分类

给定一个包含红色、白色和蓝色、共 n 个元素的数组 nums ,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。必须在不使用库内置的 sort 函数的情况下解决这个问题。

from typing import List

class Solution:
    def sortColors(self, nums: List[int]) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """
        def swap(nums, index1, index2):
            nums[index1], nums[index2] = nums[index2], nums[index1]

        size = len(nums)
        if size < 2:
            return

        zero = 0
        two = size

        i = 0

        while i < two:
            if nums[i] == 0:
                swap(nums, i, zero)
                i += 1
                zero += 1
            elif nums[i] == 1:
                i += 1
            else:
                two -= 1
                swap(nums, i, two)

看的别人的解答,实在是很不会呀。

215.数组中的第K个最大元素

给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。

class Solution:
    def findKthLargest(self, nums: List[int], k: int) -> int:
        return sorted(nums)[len(nums) - k]

时间复杂度不符合题目要求,需要找到改进措施。

剑指offer40.最小的k个数

输入整数数组 arr ,找出其中最小的 k 个数。例如,输入4、5、1、6、2、7、3、8这8个数字,则最小的4个数字是1、2、3、4。

class Solution:
    def getLeastNumbers(self, arr: List[int], k: int) -> List[int]:
        arr.sort()
        return arr[:k]

思路:先排序,后查找。

1122.数组的相对排序

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

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

class Solution:
    def relativeSortArray(self, arr1: List[int], arr2: List[int]) -> List[int]:
        upper = max(arr1)
        frequency = [0] * (upper + 1)
        for x in arr1:
            frequency[x] += 1
        
        ans = list()
        for x in arr2:
            ans.extend([x] * frequency[x])
            frequency[x] = 0
        for x in range(upper + 1):
            if frequency[x] > 0:
                ans.extend([x] * frequency[x])
        return ans

内存占用上还有提升空间。

220.存在重复元素Ⅲ

给你一个整数数组 nums 和两个整数 indexDiff 和 valueDiff 。

找出满足下述条件的下标对 (i, j)

  • i != j,
  • abs(i - j) <= indexDiff
  • abs(nums[i] - nums[j]) <= valueDiff

如果存在,返回 true ;否则,返回 false 

注:此题困难,我不会。

164.最大间距

给定一个无序的数组 nums,返回 数组在排序之后,相邻元素之间最大的差值 。如果数组元素个数小于 2,则返回 0 。

您必须编写一个在「线性时间」内运行并使用「线性额外空间」的算法。

困难!

在此附上大佬题解

class Solution:
    def maximumGap(self, nums: List[int]) -> int:
        if len(nums)<2: return 0
        if len(nums)==2: return abs(nums[0]-nums[1])

        minnum = min(nums)
        maxnum = max(nums)
        if maxnum==minnum: return 0

        lenth = len(nums)+1 #桶的大小
        record_max = [-1]*lenth #记录当前桶的最大值
        record_min = [10**6]*lenth #记录当前桶的最大值
        hasnum = [False]*lenth #记录当前桶是否有数值
        for i in range(len(nums)):
            idx = int((nums[i]-minnum)*len(nums)/(maxnum-minnum)) #桶的索引
            if not hasnum[idx]:
                record_max[idx] = nums[i]
                record_min[idx] = nums[i]
                hasnum[idx] = True
            else:
                record_max[idx] = max(record_max[idx], nums[i])
                record_min[idx] = min(record_min[idx], nums[i])
                
        res = 0
        tmp = record_max[0]
        for i in range(1, lenth):
            if hasnum[i]:
                res = max(res, record_min[i]-tmp)
                tmp = record_max[i]
        return res

使用桶排序。这道题的难点在于如何用线性的时空复杂度来解决。直接sort然后遍历数组当然可以解决问题,但是面试的时候这种解法肯定是不能让面试官满意的。

桶排序的两个核心问题:

  1. 每个桶的长度是多少?换句话说,每个桶放置元素的范围是什么?
  2. 一共要准备多少个桶?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值