首页 > 其他分享 >【每日练习】将字符串翻转到单调递增、使字符串平衡的最少删除次数

【每日练习】将字符串翻转到单调递增、使字符串平衡的最少删除次数

时间:2023-12-18 10:47:39浏览次数:29  
标签:遍历 flips 次数 ones 字符串 单调 翻转

将字符串翻转到单调递增

https://leetcode.cn/problems/flip-string-to-monotone-increasing/

如果一个二进制字符串,是以一些 0(可能没有 0)后面跟着一些 1(也可能没有 1)的形式组成的,那么该字符串是 单调递增 的。

给你一个二进制字符串 s,你可以将任何 0 翻转为 1 或者将 1 翻转为 0

返回使 s 单调递增的最小翻转次数。

示例 1:

输入:s = "00110"
输出:1
解释:翻转最后一位得到 00111.

示例 2:

输入:s = "010110"
输出:2
解释:翻转得到 011111,或者是 000111。

示例 3:

输入:s = "00011000"
输出:2
解释:翻转得到 00000000。

提示:

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

思路

我们可以将字符串 s 分为两部分:前面的 0 和后面的 1。假设前面有 x 个 0,后面有 y 个 1,则原始的字符串可以表示为:

000...0111...111

我们需要找到最少的翻转次数,将其变为一个单调递增的字符串。考虑两种情况:

  • 将前面所有的 0 都变为 1。此时需要翻转 x 次。
  • 将后面所有的 1 都变为 0。此时需要翻转 y 次。

我们需要取这两种情况中的最小值,因为我们希望翻转次数最小。

具体实现时,我们遍历字符串 s,统计出前面的 0 的数量和后面的 1 的数量,并用变量 flips 记录当前已经进行的翻转次数。在遍历过程中,如果遇到了 '0',则将 flips 加 1,表示将该 '0' 翻转为 '1'。否则,表示遇到了 '1',那么就不需要进行翻转操作,只需要将后面的 1 的数量减 1 即可。

在遍历过程中,我们需要维护一个变量 ones,表示后面剩余的 1 的数量。将 flips 和 ones 取最小值即为当前的最小翻转次数。最后返回这个最小值即可。

以示例 1 "00110" 为例,遍历过程如下:

s: 0 0 1 1 0
   |   | |
   x   y ones

flips = 0, ones = 2
遇到 '0',将 flips 加 1,ones 不变,即 flips = 1,ones = 2

flips = 1, ones = 2
遇到 '0',将 flips 加 1,ones 不变,即 flips = 2,ones = 2

flips = 2, ones = 2
遇到 '1',将 ones 减 1,flips 不变,即 flips = 2,ones = 1

flips = 2, ones = 1
遇到 '1',将 ones 减 1,flips 不变,即 flips = 2,ones = 0

最后返回 flips,即 2。

根据结果可以看出,我们需要将前面的两个 '0' 翻转为 '1' 才能得到一个单调递增的字符串。

代码

class Solution {
public:
    int minFlipsMonoIncr(string s) {
        int ones = 0, flips = 0;//flips记录当前已经进行的翻转次数
        for (char c : s) {
            if (c == '0') {
                // 将当前的 '0' 变为 '1'
                flips++;
            } else {
                // 统计当前出现的 '1' 的数量
                ones++;
            }
            // 将 '0' 的数量与剩余的 '1' 的数量比较,取最小值
            flips = min(flips, ones);
        }
        return flips;
    }
};

使字符串平衡的最少删除次数

https://leetcode.cn/problems/minimum-deletions-to-make-string-balanced/

给你一个字符串 s ,它仅包含字符 'a''b'

你可以删除 s 中任意数目的字符,使得 s 平衡 。当不存在下标对 (i,j) 满足 i < j ,且 s[i] = 'b' 的同时 s[j]= 'a' ,此时认为 s平衡 的。

请你返回使 s 平衡最少 删除次数。

示例 1:

输入:s = "aababbab"
输出:2
解释:你可以选择以下任意一种方案:
下标从 0 开始,删除第 2 和第 6 个字符("aababbab" -> "aaabbb"),
下标从 0 开始,删除第 3 和第 6 个字符("aababbab" -> "aabbbb")。

示例 2:

输入:s = "bbaaaaabb"
输出:2
解释:唯一的最优解是删除最前面两个字符。

提示:

  • 1 <= s.length <= 105
  • s[i] 要么是 'a' 要么是 'b'

思路

题意本质上是要求输入字符串s中b不能够出现在a的前面,因此采用遍历两次的方式来做,与前面一题稍微不同

维护两个变量,res代表需要进行输出操作的次数,count4a是a出现的次数统计

第一次遍历s,我们先统计出a的数量。然后将a的数量作为删除次数的初始值

因为我们要使得字符串"平衡",一种方式是将字符串中的a全部变成b(或者把b全部变成a,两种一样)

所以这里统计出a的数量就相当于要将a变成b的次数,该次数可以作为删除操作的初始值

第二次遍历我们是要找出最少的删除操作次数,因为第一次遍历结束后我们得到的是两种情况(或者说解法):即把a全部变成b或者把b全部变成a。这两种方法虽然都是本题的一个解,但不是最优的。

因为实际上我们只需要保证b不出现在a之前就行,那么只要在遇到ba的时候把其中一个改了就可以(改谁其实无所谓)

所以,在第二次遍历的时候,我们在第一次遍历得到的解(把b全部改成a)的基础上继续优化,也就是遇到ba才改,其余情况不改

那么当再次遍历到a的时候,此时作为修改次数的count4a变量(因为要用count4a更新res,所以其也代表修改次数)要减1,用来表示此时我们不需要修改

当再次遍历遇到b的时候,此时不论后面是bb还是ba,都要进行修改操作,所以修改计数count4a要加1

每次遍历我们都更新res值,最后可以得到一个最少的修改次数

代码

#include <string>

class Solution {
public:
    int minimumDeletions(std::string s) {
        int res = 0, count4a = 0;//count代表a出现的次数,res代表需要进行删除操作的次数
        for(char c : s){        //统计一下a出现的次数
            if(c == 'a') count4a++;
        }
        //需要将res初始化为count,表示初始状态下的最少删除次数。
        res = count4a;
        for(char c : s){
            if(c == 'a') count4a--;
            else count4a++;
            res = min(res, count4a);
        }
        return res;
    }
};

标签:遍历,flips,次数,ones,字符串,单调,翻转
From: https://www.cnblogs.com/DAYceng/p/17910490.html

相关文章

  • 浅谈单调栈
    单调栈,顾名思义,具有单调性的栈。单调,指满足一个序列是一个从小到大的序列或从大到小的序列。栈(\(stack\))是以一种线性存储结构,它具有以下特点:栈中的数据元素遵守“先进后出(\(First\in\Last\out\))”的原则,简称FILO结构;限定只能在栈顶进行插入和删除操作。所以,何为单......
  • 438. 找到字符串中所有字母异位词
    1.题目介绍给定两个字符串 \(s\) 和\(p\),找到 \(s\) 中所有 \(p\) 的 异位词 的子串,返回这些子串的起始索引。不考虑答案输出的顺序。异位词指由相同字母重排列形成的字符串(包括相同的字符串)。示例 1:输入:s="cbaebabacd",p="abc"输出:[0,6]解释:起始索......
  • 浙江集训字符串专题
    \(\text{CF1207G}\)题目描述有\(n\)次操作,每一次操作描述了第\(i\)个字符串,要么是单独一个字符,要是是在第\(j\)个字符串后拼接一个字符得到。接下来又\(m\)次询问,每一次给出一个字符串问在第\(i\)个字符串中出现了多少次?思路考虑检出\(\text{ACAM}\)。一个字符串......
  • Java 字符串、数组、ArrayList转换
    Java字符串、数组、ArrayList之间的相互转换 数组转字符串importjava.util.Arrays;publicclassTest02{publicstaticvoidmain(String[]args){int[]scores1=newint[]{10,20,30,40,50};int[]scores2={10,20,30,40,50};//数......
  • string.replace()与removeprefix() 和 removesuffix()的区别 字符串技巧
    string.replace(),removeprefix()和removesuffix()是Python中的字符串方法,它们都用于修改字符串,但是它们的功能和使用方式有所不同:string.replace(old,new[,count]):这个方法会将字符串中的old子串替换为new子串。如果提供了可选参数count,则只替换前count个old子串¹......
  • 字符串基础
    字符串常用操作定义字符串时,单引号,双引号,三引号都可以 字符串拼接#字符串拼接s1='i's2='love's3='you's4=s1+''+s2+''+s3print(s4)s4=f'{s1}{s2}{s3}'print(s4)字符串切片对于字符串里的每个字符都有特定的位置索引s='testfan'从上......
  • 哈希表(HashMap)与字符串哈希
    哈希表哈希表是一种通过映射来快速查找的数据结构。其通过键值对(key-value)来存储。一个数据通过哈希函数的运算来生成一个属于他自己的键值,尔后将其与键值绑定。当我们想查找这个数据时,就可以直接通过键来访问对应的值,时间复杂度近似为O(1)。哈希表适用于这样一种场景,当数据......
  • 解决方案 | pywintypes.com_error: (-2147221005, '无效的类字符串', None, None) --P
     1背景importpythoncomimportwin32com.clientimportmathwincad=win32com.client.Dispatch("AutoCAD.Application")#强制打开cad,该句发生报错信息doc=wincad.ActiveDocumentdoc.Utility.Prompt("Hello!Autocadfrompywin32com.\n")msp=doc.Mode......
  • 代码随想录算法训练营Day3 | 203.移除链表元素、707.设计链表、206.翻转链表
    这三道题都不涉及什么难以理解的算法,是对链表基础知识的一个复习巩固对于有数据结构基础的同学来说这个没有什么难度但是,写代码的过程中,我明显感觉到,我需要更加完善和统一的代码风格,作为一个前OIer,我的c和cpp混用的情况在基础数据结构的封装层面造成了不小的混乱!我需要去补充c......
  • 【kmp算法】字符串匹配
    一,解决问题kmp算法解决的是字符串匹配的问题,具体来说假定我们要在主串s[]中匹配模式串p[],找到匹配到的位置loc;二,具体实现和演变过程最自然的想法是暴力写法(BF)枚举主串字符s[i],和模式串p[j]。一个一个匹配,如果匹配失败,i指针回退回起点,往前进一位,再次进行比较,......