lc -- 第 121 场双周赛(bfs, 数位dp, python3, go)
简单模拟
class Solution: def missingInteger(self, nums: List[int]) -> int: res = nums[0] for i in range(1, len(nums)): if nums[i] == nums[i - 1] + 1: res += nums[i] else: break for i in itertools.count(res, 1): if i not in nums: return i return 0
func missingInteger(nums []int) int { sum := nums[0] n := len(nums) for i := 1; i < n && nums[i] == nums[i - 1] + 1; i ++ { sum += nums[i] } mp := map[int]bool{} for _, v := range nums { mp[v] = true } for i := sum; i < 3000; i ++ { if !mp[i] { return i } } return 0 }
利用异或的性质
class Solution: def minOperations(self, nums: List[int], k: int) -> int: t = 0 for x in nums: t ^= x t ^= k return t.bit_count()
func minOperations(nums []int, k int) int { for _, x := range nums { k ^= x } return bits.OnesCount(uint(k)) }
广度优先搜索
class Solution: def minimumOperationsToMakeEqual(self, x: int, y: int) -> int: qx = deque() stx = set() stx.add(x) qx.append(x) res = 0 while len(qx) > 0: m = len(qx) for i in range(m): tt = qx.popleft() if tt == y: return res if tt % 11 == 0 and tt // 11 not in stx: stx.add(tt // 11) qx.append(tt // 11) if tt % 5 == 0 and tt // 5 not in stx: stx.add(tt // 5) qx.append(tt // 5) if tt + 1 not in stx: stx.add(tt + 1) qx.append(tt + 1) if tt - 1 not in stx: stx.add(tt - 1) qx.append(tt - 1) res += 1
func minimumOperationsToMakeEqual(x int, y int) int { mp := map[int]bool{} q := []int{} q = append(q, x) mp[x] = true step := 0 for len(q) > 0 { m := len(q) for i := 0; i < m; i ++ { tt := q[0] if tt == y { return step } q = q[1:] if !mp[tt - 1] { q = append(q, tt - 1) mp[tt - 1] = true } if !mp[tt + 1] { q = append(q, tt + 1) mp[tt + 1] = true } if tt % 11 == 0 && !mp[tt / 11] { q = append(q, tt / 11) mp[tt / 11] = true } if tt % 5 == 0 && !mp[tt / 5] { q = append(q, tt / 5) mp[tt / 5] = true } } step ++ } return 0 }
最后一题是数位dp, 灵神在这个题目中讲解了数位dp 2.0模板;
可以点击看一看灵神讲的这个模板,太妙了. 网址:https://leetcode.cn/problems/count-the-number-of-powerful-integers/solutions/2595149/shu-wei-dp-shang-xia-jie-mo-ban-fu-ti-da-h6ci/
class Solution: def numberOfPowerfulInt(self, start: int, finish: int, limit: int, s: str) -> int: low = str(start) high = str(finish) n = len(high) low = '0' * (n - len(low)) + low # 把数位补齐,方便使用 diff = n - len(s) @cache def dfs(i: int, limit_low: bool, limit_high: bool) -> int: if i == n: return 1 # 第i个位置可以从哪里枚举到哪里 lo = int(low[i]) if limit_low else 0 hi = int(high[i]) if limit_high else 9 res = 0 if i < diff: for d in range(lo, min(hi, limit) + 1): res += dfs(i + 1, limit_low and d == lo, limit_high and d == hi) else: # 必须填int(s[i-diff]) x = int(s[i - diff]) if lo <= x <= min(hi, limit): res = dfs(i + 1, limit_low and x == lo, limit_high and x == hi) return res return dfs(0, True, True)
func numberOfPowerfulInt(start int64, finish int64, limit int, s string) int64 { low := strconv.FormatInt(start, 10) high := strconv.FormatInt(finish, 10) n := len(high) low = strings.Repeat("0", n - len(low)) + low diff := n - len(s) memo := make([]int64, n) for i := range memo { memo[i] = -1 } var dfs func(int, bool, bool) int64 dfs = func(i int, limitLow, limitHigh bool) (res int64) { if i == n { return 1 } if !limitLow && !limitHigh { p := &memo[i] if *p >= 0 { return *p } defer func() {*p = res}() } lo := 0 if limitLow { lo = int(low[i] - '0') } hi := 9 if limitHigh { hi = int(high[i] - '0') } if i < diff { for d := lo; d <= min(hi, limit); d ++ { res += dfs(i + 1, limitLow && d == lo, limitHigh && d == hi) } } else { x := int(s[i - diff] - '0') if lo <= x && x <= min(hi, limit) { res += dfs(i + 1, limitLow && x == lo, limitHigh && x == hi) } } return res } return dfs(0, true, true) }