前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >2024-05-04:用go语言,给定一个起始索引为0的字符串s和一个整数k。 要进行分割操作,直到字符串s为空: 选择s的最长

2024-05-04:用go语言,给定一个起始索引为0的字符串s和一个整数k。 要进行分割操作,直到字符串s为空: 选择s的最长

作者头像
福大大架构师每日一题
发布2024-05-17 13:58:14
1330
发布2024-05-17 13:58:14
举报

2024-05-04:用go语言,给定一个起始索引为0的字符串s和一个整数k。

要进行分割操作,直到字符串s为空:

选择s的最长前缀,该前缀最多包含k个不同字符;

删除该前缀,递增分割计数。如果有剩余字符,它们保持原来的顺序。

在操作之前,可以修改字符串s中的一个字符为另一个小写英文字母。

在最佳情况下修改至多一次字符后,返回操作结束时得到的最大分割数量。

输入:s = "accca", k = 2。

输出:3。

答案2024-05-04:

chatgpt

题目来自leetcode3003。

大体步骤如下:

1.创建一个递归函数dfs,用于计算分割得到的最大数量。

2.函数中,首先检查是否到达字符串末尾,若是则返回 1(表示完成一个分割)。

3.使用memo记录中间结果,加快计算速度。

4.对于当前处理的字符s[i],如果不将其作为新的分割点,继续处理下一个字符。

5.如果将s[i]作为新的分割点,并且新的字符数量不超过k,则继续向后处理。

6.如果未修改过字符,则尝试修改s[i]为其他26个小写字母,然后继续考虑分割带来的最大数量。

7.在每一步中,根据是否修改过字符,记录当前的最大分割数量。

8.最终返回得到的最大分割数量。

总的时间复杂度为 O(n \cdot 2^{26}),其中n为字符串长度,2^{26}表示尝试修改字符的可能性数目。

总的额外空间复杂度为O(n \cdot 2^{26}),主要由memo中间结果记录所占用的空间引起。

Go完整代码如下:

代码语言:javascript
复制
package main

import (
    "fmt"
    "math/bits"
)

func max(x, y int) int {
    if x > y {
        return x
    }
    return y
}

func maxPartitionsAfterOperations(s string, k int) int {
    n := len(s)
    type args struct {
        i, mask int
        changed bool
    }
    memo := map[args]int{}
    var dfs func(int, int, bool) int
    dfs = func(i, mask int, changed bool) (res int) {
        if i == n {
            return 1
        }

        a := args{i, mask, changed}
        if v, ok := memo[a]; ok { // 之前计算过
            return v
        }

        // 不改 s[i]
        bit := 1 << (s[i] - 'a')
        newMask := mask | bit
        if bits.OnesCount(uint(newMask)) > k {
            // 分割出一个子串,这个子串的最后一个字母在 i-1
            // s[i] 作为下一段的第一个字母,也就是 bit 作为下一段的 mask 的初始值
            res = dfs(i+1, bit, changed) + 1
        } else { // 不分割
            res = dfs(i+1, newMask, changed)
        }

        if !changed {
            // 枚举把 s[i] 改成 a,b,c,...,z
            for j := 0; j < 26; j++ {
                newMask := mask | 1<<j
                if bits.OnesCount(uint(newMask)) > k {
                    // 分割出一个子串,这个子串的最后一个字母在 i-1
                    // j 作为下一段的第一个字母,也就是 1<<j 作为下一段的 mask 的初始值
                    res = max(res, dfs(i+1, 1<<j, true)+1)
                } else { // 不分割
                    res = max(res, dfs(i+1, newMask, true))
                }
            }
        }

        memo[a] = res // 记忆化
        return res
    }
    return dfs(0, 0, false)
}

func main() {
    s := "accca"
    k := 2
    result := maxPartitionsAfterOperations(s, k)
    fmt.Println(result)
}

Python完整代码如下:

代码语言:javascript
复制
# -*-coding:utf-8-*-

def max_partitions_after_operations(s, k):
    n = len(s)
    memo = {}

    def dfs(i, mask, changed):
        if i == n:
            return 1

        a = (i, mask, changed)
        if a in memo:
            return memo[a]

        res = 0
        bit = 1 << (ord(s[i]) - ord('a'))
        new_mask = mask | bit

        if bin(new_mask).count('1') > k:
            res = dfs(i + 1, bit, changed) + 1
        else:
            res = dfs(i + 1, new_mask, changed)

        if not changed:
            for j in range(26):
                new_mask = mask | 1 << j
                if bin(new_mask).count('1') > k:
                    res = max(res, dfs(i + 1, 1 << j, True) + 1)
                else:
                    res = max(res, dfs(i + 1, new_mask, True))

        memo[a] = res
        return res

    return dfs(0, 0, False)

s = "accca"
k = 2
result = max_partitions_after_operations(s, k)
print(result)
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-05-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 福大大架构师每日一题 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 大体步骤如下:
  • Go完整代码如下:
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档