[M模拟] lc2182. 构造限制重复的字符串(贪心+模拟+复看)

本文介绍了如何使用贪心策略解决LeetCode题目中的重复限制字符串构造问题,通过哈希计数和逆序构造,避免了复杂的排序操作,同时分析了时间复杂度。
摘要由CSDN通过智能技术生成

1. 题目来源

链接:2182. 构造限制重复的字符串
力扣题解:[C++] 贪心+模拟,分类讨论,注释清晰

2. 题目解析

很明显贪心,有最大尽可能多的填最大,发现达到限制数后,就换个次大值进来,接着尽可能多的填最大。
这里就有两个想法:
1- 直接哈希计数后,根据规则,构造结果字符串
2- sort 排序后,原字符串进行判断、交换等操作,获取结果(仔细想想异常情况太多,没考虑了)

这里需要体会下与官解双指针写法的不通,感觉那个更优雅点…这种写法把算法题写成了纯业务题…


  • 时间复杂度 O ( n ) O(n) O(n) 感觉是,会比 O(n) 大,因为可能存在一些无效的遍历
  • 空间复杂度 O ( 1 ) O(1) O(1)

class Solution {
public:
    string repeatLimitedString(string s, int repeatLimit) {
        int um[26] = {0};
        for (char &c : s) um[c - 'a'] ++ ;  // 哈希计数

        string res = "";
        int last = -1, cnt = -1;    // last:当前构造字符串的末尾元素,cnt:当前构造字符串的末尾连续元素个数
        while (1) {
            bool out = true;        // 是否构造完毕标志
            for (int i = 25; i >= 0; i -- ) {   // 逆序构造结果
                if (um[i] == 0) continue ;

                if (cnt == repeatLimit) { // 如果连续元素已经满了,需要找下一个合适的字符
                    if (i != last && um[i] > 0) { // 筛选规则:下一个与当前不同,且字符尽可能大,配合上逆序添加的性质,只要遇到第一个不和末尾字符相同的可用字符即可,这里只需要一个字符
                        res += string(1, i + 'a');
                        um[i] -- ;
                        last = i, cnt = 1;
                        out = false;
                        break;
                    }
                } else {    // 末尾元素没满,看看当前元素可以放几个进去
                    if (um[i] >= repeatLimit) { // 如果当前元素较多,大于了限制数
                        if (last != i) {        // 如果末尾和当前待放入的元素不同,则直接放满限制数个字符
                            res += string(repeatLimit, i + 'a');
                            um[i] -= repeatLimit;
                            last = i, cnt = repeatLimit;    // 更新末尾元素,更新连续元素个数
                            out = false;
                        } else {    // 如果末尾和当前待放入的元素相同,那么只能放入一部分,该部分和末尾字符加在一起补充满限制数
                            int t = repeatLimit - cnt;
                            res += string(t, i + 'a');
                            um[i] -= t;
                            last = i, cnt = repeatLimit;    // 更新末尾元素,更新连续元素个数
                            out = false;
                        }
                    } else {    // 如果末尾元素不是很多,少于限制数
                        // if (last != i) {    // 如果末尾和当前待放入的元素不同,则直接放满限制数即可
                            res += string(um[i], i + 'a');
                            um[i] = 0;
                            last = i, cnt = um[i];
                            out = false;
                        // } else {   // 如果末尾和当前待放入的元素相同,那么也要考虑剩余部分放进入会不会导致超出限制,只能放入一部分,补充满限制数字符
                        //     int t = um[i] + cnt > repeatLimit ? repeatLimit - cnt : um[i];
                        //     res += string(t, i + 'a');
                        //     um[i] -= t;
                        //     last = i, cnt += t;
                        //     out = false;
                        // }

                        // 这里将上面代码注释的原因:该场景存在,但不用分类讨论,因为不会超过限制,直接添加所有字符即可
                        // 因为走到 else 逻辑, um[i] 肯定小于限制,且当前的 i 即便和 last 同一个字符,但此时的last只有一个字符
                        // 填充了多个字符--》选择次大值--》刚好次大值选中了当前的这个字符,填充一个--》该字符元素没超过限制数--》该字符走到当前逻辑
                        // 所以,只有一个字符的情况下,且剩余字符数本身就小于限制数,所以直接将剩余的所有字符全部添加进去即可

                    }
                }
            }
            if (out) return res;
        }

        return "";
    }
};
Sure! Here's your code with comments added: ```matlab F = zeros(length(z), 1); % Initialize the F vector with zeros for i = 1:length(z) % Define the Phi function using anonymous function Phi = @(theta, R, r) (z(i) + lc - lm) .* r.R .(R - r.sin(theta)) ./ ... ((R.^2 + r.^2 - 2*R.*r.*sin(theta)).sqrt(R.^2 + r.^2 + (z(i) + lc - lm).^2 - 2*R.*r.*sin(theta))) + ... (z(i) - lc + lm) .* r.R .(R - r.sin(theta)) ./ ... ((R.^2 + r.^2 - 2*R.*r.*sin(theta)).sqrt(R.^2 + r.^2 + (z(i) - lc + lm).^2 - 2*R.*r.*sin(theta))) + ... (z(i) + lc + lm) .* r.R .(R - r.sin(theta)) ./ ... ((R.^2 + r.^2 - 2*R.*r.*sin(theta)).sqrt(R.^2 + r.^2 + (z(i) + lc + lm).^2 - 2*R.*r.*sin(theta))) + ... (z(i) - lc - lm) .* r.R .(R - r.sin(theta)) ./ ... ((R.^2 + r.^2 - 2*R.*r.sin(theta)).sqrt(R.^2 + r.^2 + (z(i) - lc - lm).^2 - 2*R.*r.sin(theta))); % Calculate the value of F(i) using the integral3 function F(i) = BrNI / (4 * lc * (Rc - rc)) * integral3(Phi, 0, 2*pi, rc, Rc, rm, Rm); end ``` This code calculates the values of the vector `F` using a loop. The `Phi` function is defined as an anonymous function that takes `theta`, `R`, and `r` as input parameters. It performs a series of calculations and returns a value. The integral of `Phi` is then calculated using the `integral3` function. The result is stored in the corresponding element of the `F` vector. Please note that I have made some assumptions about the variables and functions used in your code since I don't have the complete context. Feel free to modify or clarify anything as needed.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ypuyu

如果帮助到你,可以请作者喝水~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值