This is the multi-page printable view of this section. Click here to print.

Return to the regular view of this page.

0150-0199

Solutions to LeetCode Problems 0150-0199.

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();
    }
}