贪心算法的初涉(双指针 + “过山车思想”)

"过山车"思想

首先我们用一道力扣的题目,来简单了解一下"过山车思想"

3228. 将 1 移动到末尾的最大操作次数 - 力扣(LeetCode)

给你一个

二进制字符串

s

你可以对这个字符串执行 任意次 下述操作:

  • 选择字符串中的任一下标 ii + 1 < s.length ),该下标满足 s[i] == '1's[i + 1] == '0'
  • 将字符 s[i]右移 直到它到达字符串的末端或另一个 '1'。例如,对于 s = "010010",如果我们选择 i = 1,结果字符串将会是 s = "0++001++10"

返回你能执行的最大操作次数。

示例 1:

输入: s = "1001101"

输出: 4

解释:

可以执行以下操作:

  • 选择下标 i = 0。结果字符串为 s = "++001++1101"
  • 选择下标 i = 4。结果字符串为 s = "0011++01++1"
  • 选择下标 i = 3。结果字符串为 s = "001++01++11"
  • 选择下标 i = 2。结果字符串为 s = "00++01++111"

示例 2:

输入: s = "00111"

输出: 0

提示:

  • 1 <= s.length <= 105
  • s[i]'0''1'

思路就是:想象一个过山车,所有的"1"都是小车,如果遇到了就连起来(长度是cnt),所有"0"都是关卡,当小车碰到关卡时:ans += cnt

代码:

cpp 复制代码
class Solution {
public:
    int maxOperations(string s) {
        int n = s.size(),ans = 0,cnt = 0;
        for(int i=0;i<n;i++){
            if(s[i] == '1') cnt ++;
            else if(i && s[i-1] == '1') ans += cnt;
        }
        return ans;
    }
};

双指针

我们来看一个升级版的:双指针+"过山车"

题目来自codeforces,这个平台对于思维的提升非常非常大,如果你需要很强大的思维,这个平台非常适合你

Problem - 1896B - Codeforces

You are given a string ss of length nn consisting of characters AA and BB. You are allowed to do the following operation:

  • Choose an index 1≤i≤n−1 such that si=Aand si+1=B. Then, swap si and si+1.

You are only allowed to do the operation at most once for each index 1≤i≤n−1. However, you can do it in any order you want. Find the maximum number of operations that you can carry out.

Input

Each test contains multiple test cases. The first line contains the number of test cases tt (1≤t≤10001≤t≤1000). Description of the test cases follows.

The first line of each test case contains a single integer nn (2≤n≤2⋅10^5) --- the length of string ss.

The second line of each test case contains the string ss (si=A or si=B).

It is guaranteed that the sum of nn over all test cases does not exceed 2⋅10^5.

Output

For each test case, print a single integer containing the maximum number of operations that you can carry out.

题目的意思大致是:给定一个只包含"AB"的字符串,如果字串是"AB"这种形式那么可以交换i与i+1的位置变成"BA",每个i只能与前面的i+1交换一次

那还是"过山车"思想,所有的"A"是小车,"B"是关卡,但是这里注意的是交换位置。

比如:"AABB",最后应该变成的是:"BABA" 而不是 "BBAA"

这里的话就需要一个双指针来每次更新位置

如果是我们需要找到最左边"A"的位置已经最后边"B"的位置,然后ans += right - left,left = right

为了防止越界每次输入的字符串s后面加一个"C"(这个随便加,加什么都行)然后每次right多走一步

代码:

cpp 复制代码
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <cstring>
using namespace std;

int main()
{
    int n,t;
    string s;
    cin >> t;
    while(t --){
        cin >> n >> s;
        s += 'C';
        int l = 0,r = 0,ans = 0;
        while(s[l] == 'B') l ++,r ++;
        while(l < n){
            int cnt = 0;
            while(s[r] == 'A') r ++;
            while(s[r] == 'B') r ++,cnt ++;
            // cout << cnt << " " << l << " " << r << endl;
            if(cnt){
                ans += r - l - 1;
                l = r - 1;
            }else break;
        }
        cout << ans << endl;
    }
    return 0;
}

加油

相关推荐
KeithTsui5 分钟前
GCC RISCV 后端 -- 控制流(Control Flow)的一些理解
linux·c语言·开发语言·c++·算法
mNinGInG19 分钟前
c++练习
开发语言·c++·算法
纪元A梦1 小时前
分布式锁算法——基于ZooKeeper的分布式锁全面解析
java·分布式·算法·zookeeper
Panesle1 小时前
广告推荐算法:COSMO算法与A9算法的对比
人工智能·算法·机器学习·推荐算法·广告推荐
月亮被咬碎成星星1 小时前
LeetCode[15]三数之和
数据结构·算法·leetcode
飞川撸码2 小时前
【LeetCode 热题100】240:搜索二维矩阵 II(详细解析)(Go语言版)
leetcode·矩阵·golang
半盏茶香2 小时前
启幕数据结构算法雅航新章,穿梭C++梦幻领域的探索之旅——堆的应用之堆排、Top-K问题
java·开发语言·数据结构·c++·python·算法·链表
小竹子142 小时前
L1-1 天梯赛座位分配
数据结构·c++·算法
董董灿是个攻城狮2 小时前
Transformer 通关秘籍8:词向量如何表示近义词?
算法
独好紫罗兰3 小时前
洛谷题单2-P5712 【深基3.例4】Apples-python-流程图重构
开发语言·python·算法