Every day a Leetcode
题目来源:3228. 将 1 移动到末尾的最大操作次数
解法1:遍历 + 贪心
把 1 当作车,想象有一条长为 n 的道路上有一些车。
我们要把所有的车都排到最右边,例如 011010 最终要变成 000111。
如果我们优先操作右边的车,那么每辆车都只需操作一次。如果我们优先操作左边的(能移动的)车,这会制造大量的「堵车」,那么每辆车的操作次数就会更多。
算法:
- 从左到右遍历 s,同时用一个变量 cnt1 维护遍历到的 1 的个数。
- 如果 s[i] 是 1,把 cnt1 增加 1。
- 如果 s[i] 是 0 且 s[i−1] 是 1,意味着我们找到了一段道路,可以让 i 左边的每辆车都操作一次,把答案增加 cnt1。
- 遍历结束,返回答案。
代码:
/** @lc app=leetcode.cn id=3228 lang=cpp** [3228] 将 1 移动到末尾的最大操作次数*/// @lc code=start
class Solution
{
public:int maxOperations(string s){int n = s.length();int ans = 0, cnt1 = 0;for (int i = 0; i < n; i++){if (s[i] == '1')cnt1++;else if (i > 0 && s[i - 1] == '1')ans += cnt1;}return ans;}
};
// @lc code=end
结果:
复杂度分析:
时间复杂度:O(n),其中 n 是字符串 s 的长度。
空间复杂度:O(1)。