剑指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
和 arr2
,arr2
中的元素各不相同,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然后遍历数组当然可以解决问题,但是面试的时候这种解法肯定是不能让面试官满意的。
桶排序的两个核心问题:
- 每个桶的长度是多少?换句话说,每个桶放置元素的范围是什么?
- 一共要准备多少个桶?