lc -- 第 121 场双周赛(bfs, 数位dp, python3, go)

发布时间 2024-01-08 10:13:43作者: 深渊之巅

 简单模拟

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