欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 新车 > 力扣 411周赛

力扣 411周赛

2024/10/22 23:47:54 来源:https://blog.csdn.net/qq_53674101/article/details/141403563  浏览:    关键词:力扣 411周赛

统计满足K约束的子字符串数量 I

给你一个 二进制 字符串 s 和一个整数 k。
如果一个 二进制字符串 满足以下任一条件,则认为该字符串满足 k 约束:
字符串中 0 的数量最多为 k。
字符串中 1 的数量最多为 k。
返回一个整数,表示 s 的所有满足 k 约束 的子字符串的数量。输入:s = "10101", k = 1
输出:12
解释:s 的所有子字符串中,除了 "1010"、"10101" 和 "0101" 外,其余子字符串都满足 k 约束。提示:
1 <= s.length <= 50
1 <= k <= s.length
s[i] 是 '0' 或 '1'。

分析问题:

  1. 长度不大于K的字符串肯定符合条件
  2. 字符串的长度最大为50,复杂度可以为 l o g ( n 3 ) log(n^3) log(n3)
    我想到的方法是:用前缀和做,表示 0 - i (假设当前位置为i) 分别有多少个0和1,最后,只需要枚举长度大于k的字符串的左右边界加上长度不大于k的字符串的个数 ( n + n − k + 1 ) ∗ ( k − 1 ) / 2 (n + n-k+1) * (k - 1) / 2 (n+nk+1)(k1)/2

const int N = 60;
class Solution {
public:int cnt[N];int countKConstraintSubstrings(string s, int k) {int n = s.size();int ans = 0;int t = min(n, k);ans += (n + n - t + 1) * t / 2;for (int i = 1; i <= n; i++) {if (s[i-1] == '1') cnt[i] = 1;cnt[i] += cnt[i - 1];}for (int i = 0; i < n; i++) {for (int j = i + k + 1; j <= n; j++) {int t = cnt[j] - cnt[i];if (t <= k || j - i - t <= k) ans++;}}return ans;}
};

超级饮料的最大强化能量

来自未来的体育科学家给你两个整数数组 energyDrinkA 和 energyDrinkB,数组长度都等于 n。这两个数组分别代表 A、B 两种不同能量饮料每小时所能提供的强化能量。
你需要每小时饮用一种能量饮料来 最大化 你的总强化能量。然而,如果从一种能量饮料切换到另一种,你需要等待一小时来梳理身体的能量体系(在那个小时里你将不会获得任何强化能量)。
返回在接下来的 n 小时内你能获得的 最大 总强化能量。
注意 你可以选择从饮用任意一种能量饮料开始。示例 1:
输入:energyDrinkA = [1,3,1], energyDrinkB = [3,1,1]
输出:5
解释:
要想获得 5 点强化能量,需要选择只饮用能量饮料 A(或者只饮用 B)。
示例 2:
输入:energyDrinkA = [4,1,1], energyDrinkB = [1,1,3]
输出:7
解释:
第一个小时饮用能量饮料 A。
切换到能量饮料 B ,在第二个小时无法获得强化能量。
第三个小时饮用能量饮料 B ,并获得强化能量。提示:
n == energyDrinkA.length == energyDrinkB.length
3 <= n <= 105
1 <= energyDrinkA[i], energyDrinkB[i] <= 105

解题思路:用动态规划来做。
公式( f[i][0] 表示i位置不喝饮料,f[i][1]表示i位置喝 a 饮料,f[i][2] 表示i位置喝 b 饮料 ):
f [ i ] [ 0 ] = m a x ( f [ i − 1 ] [ 0 ] , f [ i − 1 ] [ 1 ] , f [ i − 1 ] [ 2 ] ) f[i][0] = max(f[i-1][0], f[i-1][1], f[i-1][2]) f[i][0]=max(f[i1][0],f[i1][1],f[i1][2])
f [ i ] [ 1 ] = m a x ( f [ i − 1 ] [ 0 ] , f [ i − 1 ] [ 1 ] ) + a [ i ] f[i][1] = max(f[i-1][0], f[i-1][1]) + a[i] f[i][1]=max(f[i1][0],f[i1][1])+a[i]
f [ i ] [ 2 ] = m a x ( f [ i − 1 ] [ 0 ] , f [ i − 1 ] [ 2 ] ) + b [ i ] f[i][2] = max(f[i-1][0], f[i-1][2]) + b[i] f[i][2]=max(f[i1][0],f[i1][2])+b[i]

找出最大的N位K回文数

我分析的方法:用9填充(n+1)/2位数,从后往前一次递减遍历每位数,从后往前遍历这个数添加到这个数的末尾形成回文数直到可以被k整除。
判断是否是k的倍数,可以每次加一个数时都对加和取余,不影响结果。
这个方法会超时

const int N = 1e5 +10;
class Solution {
public:int n, k;char str[N];string ans;void dfs(int pos) {if(ans.size()) return;int t = (n + 1) >> 1;if (pos == t) {long long p = 0;for (int i = 0; i < n; i++) {p = (p * 10 % k + str[i < t ? i : (n / 2 - 1 - i % t)] - '0') % k;//  cout << str[i < t ? i : (n / 2 - 1 - i % t)];}//  cout << endl;//  cout << "p=" << p <<endl;if (!p) {ans = "";for(int i=0; i < n; i++) ans += str[i < t ? i : (n / 2 - 1 - i % t)];return;}return;}for (char c = '9'; c >= '0'; c--) {str[pos] = c;dfs(pos + 1);}}string largestPalindrome(int n, int k) {this->n = n;this->k = k;dfs(0);return ans;}
};

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com