KK's blog

每天积累多一些

0%

LeetCode



Given an array of strings words and an integer k, return the k most frequent strings.

Return the answer sorted by the frequency from highest to lowest. Sort the words with the same frequency by their lexicographical order.

Example 1:

Input: words = [“i”,”love”,”leetcode”,”i”,”love”,”coding”], k = 2
Output: [“i”,”love”]
Explanation: “i” and “love” are the two most frequent words.
Note that “i” comes before “love” due to a lower alphabetical order.


Example 2:

Input: words = [“the”,”day”,”is”,”sunny”,”the”,”the”,”the”,”sunny”,”is”,”is”], k = 4
Output: [“the”,”is”,”sunny”,”day”]
Explanation: “the”, “is”, “sunny” and “day” are the four most frequent words, with the number of occurrence being 4, 3, 2 and 1 respectively.


Constraints:

1 <= words.length <= 500 1 <= words[i] <= 10
words[i] consists of lowercase English letters. k is in the range [1, The number of **unique** words[i]]

Follow-up: Could you solve it in O(n log(k)) time and O(n) extra space?

题目大意:

求k个最高频率的单词

解题思路:

N/A

解题步骤:

N/A

注意事项:

  1. 若频率一样,就按字母顺序lexicographical. 所以用大小为k的heap做比较困难。直接用排序即可

Python代码:

1
2
3
4
5
def topKFrequent(self, words: List[str], k: int) -> List[str]:
freq_dict = collections.Counter(words)
li = [(freq, word) for word, freq in freq_dict.items()]
li.sort(key=lambda x : (-x[0], x[1]))
return [pair[1] for pair in li[:k]]

算法分析:

时间复杂度为O(nlogn),空间复杂度O(n)

LeetCode



Given two integer arrays nums1 and nums2, return the maximum length of a subarray that appears in both arrays.

Example 1:

Input: nums1 = [1,2,3,2,1], nums2 = [3,2,1,4,7]
Output: 3
Explanation: The repeated subarray with maximum length is [3,2,1].


Example 2:

Input: nums1 = [0,0,0,0,0], nums2 = [0,0,0,0,0]
Output: 5


Constraints:

1 <= nums1.length, nums2.length <= 1000 0 <= nums1[i], nums2[i] <= 100

题目大意:

两数组的最长相等子数组

解题思路:

由于是两数组匹配,所以是匹配性DP
dp[i][j]为以nums1[i-1], nums2[j-1]为结尾的最长重复数组,答案为滚动最大值

1
2
dp[i][j] = dp[i-1][j-1] + 1 if nums1[i-1] == nums2[j-1]
= 0 if nums1[i-1] != nums2[j-1]

类似题目:
LeetCode 1143 Longest Common Subsequence, 求最长公共子字符串
Karat 002 Longest Common Continuous Subarray 一样的题目,结果类型不同:最长长度和结果

解题步骤:

N/A

注意事项:

Python代码:

1
2
3
4
5
6
7
8
9
10
11
# dp[i][j] = dp[i-1][j-1] + 1 if nums1[i-1] == nums2[j-1]
# = 0 if nums1[i-1] != nums2[j-1]
def findLength(self, nums1: List[int], nums2: List[int]) -> int:
max_length = 0
dp = [[0 for _ in range(len(nums2) + 1)] for _ in range(len(nums1) + 1)]
for i in range(1, len(dp)):
for j in range(1, len(dp[0])):
if nums1[i - 1] == nums2[j - 1]:
dp[i][j] = dp[i - 1][j - 1] + 1
max_length = max(max_length, dp[i][j])
return max_length

算法分析:

时间复杂度为O(n2),空间复杂度O(n2)

LeetCode



A peak element is an element that is strictly greater than its neighbors.

Given an integer array nums, find a peak element, and return its index. If the array contains multiple peaks, return the index to any of the peaks.

You may imagine that nums[-1] = nums[n] = -∞.

You must write an algorithm that runs in O(log n) time.

Example 1:

Input: nums = [1,2,3,1]
Output: 2
Explanation: 3 is a peak element and your function should return the index number 2.


Example 2:

Input: nums = [1,2,1,3,5,6,4]
Output: 5
Explanation: Your function can return either index number 1 where the peak element is 2, or index number 5 where the peak element is 6.


Constraints:

1 <= nums.length <= 1000 -2<sup>31</sup> <= nums[i] <= 2<sup>31</sup> - 1
* nums[i] != nums[i + 1] for all valid i.

题目大意:

找数组极大值

解题思路:

N/A

解题步骤:

N/A

注意事项:

  1. mid - 1 >= 0

Python代码:

1
2
3
4
5
6
7
8
9
def findPeakElement(self, nums: List[int]) -> int:
start, end = 0, len(nums) - 1
while start + 1 < end:
mid = start + (end - start) // 2
if mid >= 1 and nums[mid - 1] < nums[mid]:
start = mid
else:
end = mid
return start if nums[start] > nums[end] else end
1
2
3
4
5
6
7
8
9
def findValleyElement(self, nums: List[int]) -> int:
start, end = 0, len(nums) - 1
while start + 1 < end:
mid = start + (end - start) // 2
if mid >= 1 and nums[mid - 1] >= nums[mid]:
start = mid
else:
end = mid
return start if nums[start] <= nums[end] else end

算法分析:

时间复杂度为O(logn),空间复杂度O(1)

LeetCode



Roman numerals are represented by seven different symbols: I, V, X, L, C, D and M.

Symbol       Value
I 1
V 5
X 10
L 50
C 100
D 500
M 1000


For example, 2 is written as II in Roman numeral, just two one’s added together. 12 is written as XII, which is simply X + II. The number 27 is written as XXVII, which is XX + V + II.

Roman numerals are usually written largest to smallest from left to right. However, the numeral for four is not IIII. Instead, the number four is written as IV. Because the one is before the five we subtract it making four. The same principle applies to the number nine, which is written as IX. There are six instances where subtraction is used:

I can be placed before V (5) and X (10) to make 4 and 9. X can be placed before L (50) and C (100) to make 40 and 90.
C can be placed before D (500) and M (1000) to make 400 and 900.

Given an integer, convert it to a roman numeral.

Example 1:

Input: num = 3
Output: “III”
Explanation: 3 is represented as 3 ones.


Example 2:

Input: num = 58
Output: “LVIII”
Explanation: L = 50, V = 5, III = 3.


Example 3:

Input: num = 1994
Output: “MCMXCIV”
Explanation: M = 1000, CM = 900, XC = 90 and IV = 4.


Constraints:
1 <= num <= 3999

题目大意:

阿拉伯数字转罗马数字

解题思路(推荐):

本质上和算法二一样,但优化了代码。map的内容是一样的但变成list保证顺序,然后从大到小遍历这个map,商对应的symbol放入结果,余数进入下一轮

注意事项:

  1. map的内容是一样的但变成list保证顺序,然后从大到小遍历这个map,商对应的symbol放入结果,余数进入下一轮

Python代码:

1
2
3
4
5
6
7
8
9
def intToRoman(self, num: int) -> str:
INT_TO_ROMAN = [(1000, 'M'), (900, 'CM'), (500, 'D'), (400, 'CD'), (100, 'C'),
(90, 'XC'), (50, 'L'), (40, 'XL'), (10, 'X'), (9, 'IX'), (5, 'V'),
(4, 'IV'), (1, 'I')]
res = ''
for n, symbol in INT_TO_ROMAN:
count, num = num // n, num % n
res += symbol * count
return res

算法分析:

时间复杂度为O(1),空间复杂度O(1)


算法II解题思路:

N/A

解题步骤:

N/A

注意事项:

  1. 用int to english的递归方法,将固定值放入到Map中
  2. 分界点为[4, 5, 9 10], [40, 50, 90, 100]进行递归

Python代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
def intToRoman2(self, num: int) -> str:
INT_TO_ROMAN = {
0: '',
4: 'IV',
5: 'V',
9: 'IX',
10: 'X',
40: 'XL',
50: 'L',
90: 'XC',
100: 'C',
400: 'CD',
500: 'D',
900: 'CM',
1000: 'M',
}
if num in INT_TO_ROMAN:
return INT_TO_ROMAN[num]
elif num < 4:
return 'I' * num
elif num < 9:
return self.intToRoman(5) + self.intToRoman(num - 5)
elif num < 40:
return 'X' * (num // 10) + self.intToRoman(num % 10)
elif num < 50:
return self.intToRoman(40) + self.intToRoman(num - 40)
elif num < 90:
return self.intToRoman(50) + self.intToRoman(num - 50)
elif num < 100:
return self.intToRoman(90) + self.intToRoman(num % 90)
elif num < 400:
return 'C' * (num // 100) + self.intToRoman(num % 100)
elif num < 500:
return self.intToRoman(400) + self.intToRoman(num - 400)
elif num < 900:
return self.intToRoman(500) + self.intToRoman(num - 500)
elif num < 1000:
return self.intToRoman(900) + self.intToRoman(num % 900)
else:
return 'M' * (num // 1000) + self.intToRoman(num % 1000)

算法分析:

时间复杂度为O(1),空间复杂度O(1)

LeetCode



You are assigned to put some amount of boxes onto one truck. You are given a 2D array boxTypes, where boxTypes[i] = [numberOfBoxes<sub>i</sub>, numberOfUnitsPerBox<sub>i</sub>]:

numberOfBoxes<sub>i</sub> is the number of boxes of type i. numberOfUnitsPerBox<sub>i</sub>is the number of units in each box of the type i.

You are also given an integer truckSize, which is the maximum number of boxes that can be put on the truck. You can choose any boxes to put on the truck as long as the number of boxes does not exceed truckSize.

Return the maximum total number of units that can be put on the truck.

Example 1:

Input: boxTypes = [[1,3],[2,2],[3,1]], truckSize = 4
Output: 8
Explanation: There are:
- 1 box of the first type that contains 3 units.
- 2 boxes of the second type that contain 2 units each.
- 3 boxes of the third type that contain 1 unit each.
You can take all the boxes of the first and second types, and one box of the third type.
The total number of units will be = (1 3) + (2 2) + (1 1) = 8.


Example 2:

Input: boxTypes = [[5,10],[2,5],[4,7],[3,9]], truckSize = 10
Output: 91


Constraints: 1 <= boxTypes.length <= 1000
1 <= numberOfBoxes<sub>i</sub>, numberOfUnitsPerBox<sub>i</sub> <= 1000 1 <= truckSize <= 10<sup>6</sup>

题目大意:

货车能装的最大unit数,每种类型的盒都能装一定数量的units,而每种盒子占地方一样。

解题思路:

由于每种盒子占地一样,所以当然是先放unit大的。贪婪法。

解题步骤:

N/A

注意事项:

  1. 按unit数倒序排序
  2. pair是一个数组,要加pair[i][0]

Python代码:

1
2
3
4
5
6
7
8
9
10
def maximumUnits(self, boxTypes: List[List[int]], truckSize: int) -> int:
pairs = [(li[1], li[0]) for li in boxTypes]
pairs.sort(reverse=True)
res, i = 0, 0
for pair in pairs:
res += pair[0] * min(pair[1], truckSize)
truckSize -= pair[1]
if truckSize <= 0:
break
return res

算法分析:

时间复杂度为O(nlogn),空间复杂度O(n)

Free mock interview