This is the multi-page printable view of this section. Click here to print.
0150-0199
Solutions to LeetCode Problems 0150-0199.
- 1: 0187.重复的DNA序列
- 2: 0189.轮转数组
1 - 0187.重复的DNA序列
方法一:哈希表
朴素解法,用哈希表保存所有长度为 10 的子序列出现的次数,当子序列出现次数大于 1 时,把该子序列作为结果之一。
假设字符串 s
长度为 n
,则时间复杂度 $O(n \times 10)$,空间复杂度 $O(n)$。
func findRepeatedDnaSequences(s string) []string {
ans, cnt := []string{}, map[string]int{}
for i := 0; i <= len(s)-10; i++ {
sub := s[i : i+10]
cnt[sub]++
if cnt[sub] == 2 {
ans = append(ans, sub)
}
}
return ans
}
方法二:Rabin-Karp 字符串匹配算法
和0028.找出字符串中第一个匹配项的下标类似,本题可以借助哈希函数将子序列计数的时间复杂度降低到 $O(1)$。
假设字符串 s
长度为 n
,则时间复杂度为 $O(n)$,空间复杂度 $O(n)$。
func findRepeatedDnaSequences(s string) []string {
hashCode := map[byte]int{'A': 0, 'C': 1, 'G': 2, 'T': 3}
ans, cnt, left, right := []string{}, map[int]int{}, 0, 0
sha, multi := 0, int(math.Pow(4, 9))
for ; right < len(s); right++ {
sha = sha*4 + hashCode[s[right]]
if right-left+1 < 10 {
continue
}
cnt[sha]++
if cnt[sha] == 2 {
ans = append(ans, s[left:right+1])
}
sha, left = sha-multi*hashCode[s[left]], left+1
}
return ans
}
2 - 0189.轮转数组
方法一:反转数组
时间复杂度 $O(n)$,空间复杂度 $O(1)$。
先反转整个数组,再反转前 $k$ 个元素,最后反转剩余元素。
impl Solution {
pub fn rotate(nums: &mut Vec<i32>, k: i32) {
let k = k as usize % nums.len();
nums.reverse();
nums[..k].reverse();
nums[k..].reverse();
}
}