首页 > 其他分享 >力扣刷题——2516. 每种字符至少取 K 个

力扣刷题——2516. 每种字符至少取 K 个

时间:2024-09-29 10:48:40浏览次数:7  
标签:size right return int 力扣 2516 刷题 维护 left

一开始想的很简单,觉得在数组两端维护两个下标,用贪心的方法模拟取数字。

class Solution {
public:
    int takeCharacters(string s, int k) {
        int left = 0, right = s.size() - 1;
        if(k == 0)
            return 0;
        int res = 0;
        vector<int> tb(3, k);
        while(left <= right)
        {
            if(tb[s[left] - 'a'])
            {
                tb[s[left] - 'a']--;
                left++;
            }
            else if(tb[s[right] - 'a'])
            {
                tb[s[right] - 'a']--;
                right--;
            }
            else
            {
                left++;
                right--;
            }
            if(tb[0] == 0 && tb[1] == 0 && tb[2] == 0)
                return res + 1;
            res++;
        }

        return -1;
    }
};

但这样会WA,因为在取数字的时候没有办法事先知道最优解是优先取右还是取左。
比如s ="cbbac" k=1这个用例,代码是优先选左,最终得到的答案是4,但实际上这个用例是优先选右的。
既然维护选的方法不行,那么可以试试维护一个不选的滑动窗口。详细的做法是,从一开始就维护一个窗口,当排除掉这个窗口中的字母能够满足题目条件时,就输出一个答案跟之前的做比较,这样能取到所有的可能答案。

class Solution {
public:
    int takeCharacters(string s, int k) {
        int left = 0, right = s.size() - 1;
        if(k == 0)
            return 0;
        int res = 0;
        vector<int> tb(3, k);
        while(left <= right)
        {
            if(tb[s[left] - 'a'])
            {
                tb[s[left] - 'a']--;
                left++;
            }
            else if(tb[s[right] - 'a'])
            {
                tb[s[right] - 'a']--;
                right--;
            }
            else
            {
                left++;
                right--;
            }
            if(tb[0] == 0 && tb[1] == 0 && tb[2] == 0)
                return res + 1;
            res++;
        }

        return -1;
    }
};

标签:size,right,return,int,力扣,2516,刷题,维护,left
From: https://www.cnblogs.com/yuhixyui/p/18439115

相关文章

  • 2516. 每种字符至少取 K 个
    给你一个由字符'a'、'b'、'c'组成的字符串s和一个非负整数k。每分钟,你可以选择取走s最左侧还是最右侧的那个字符。你必须取走每种字符至少k个,返回需要的最少分钟数;如果无法取到,则返回-1。示例1:输入:s="aabaaaacaabc",k=2输出:8解释:从s的左侧取三个......
  • 【力扣 | SQL题 | 每日三题】力扣1068, 1204, 1193, 1084, 1141
    1.力扣1068:产品销售分析11.1题目:销售表 Sales:+-------------+-------+|ColumnName|Type|+-------------+-------+|sale_id|int||product_id|int||year|int||quantity|int||price|int|+-------------+-......
  • 力扣 简单 206.反转链表
    文章目录题目介绍题解题目介绍题解法一:双指针在遍历链表时,将当前节点的next改为指向前一个节点。由于节点没有引用其前一个节点,因此必须事先存储其前一个节点。在更改引用之前,还需要存储后一个节点。最后返回新的头引用。代码如下:classSolution{public......
  • 力扣 中等 92.反转链表 II
    文章目录题目介绍题解题目介绍题解classSolution{publicListNodereverseBetween(ListNodehead,intleft,intright){//创建一个哑节点,它的next指向头节点,方便处理ListNodedummy=newListNode(0,head);//p0用于......
  • 【2024.09.27】NOIP2024 赛前集训-刷题训练(3)
    【2024.09.27】NOIP2024赛前集训-刷题训练(3)「NOIP2018提高组」铺设道路算法一:模拟正常人铺路的过程,每次找区间的最小值,最小值就是本次填的高度,由于出现了若干个0位置,就分裂成若干个子区间去重复上述过程,直到全部变成0。时间复杂度\(O(nlogn)\),瓶颈在预处理st表。算法二:若......
  • 【算法题】72. 编辑距离-力扣(LeetCode)
    【算法题】72.编辑距离-力扣(LeetCode)1.题目下方是力扣官方题目的地址72.编辑距离给你两个单词word1和word2,请返回将word1转换成word2所使用的最少操作数。你可以对一个单词进行如下三种操作:插入一个字符删除一个字符替换一个字符示例1:输入:word1="ho......
  • 8,(经典面试题:分组求topN)Python数分之Pandas训练,力扣,1532. 最近的三笔订单
    学习:知识的初次邂逅复习:知识的温故知新练习:知识的实践应用目录一,原题力扣链接二,题干三,建表语句四,分析五,Pandas解答六,验证七,知识点总结一,原题力扣链接.-力扣(LeetCode)二,题干表:Customers+---------------+---------+|ColumnName|Type|+------......
  • 26,【经典大厂面试题】【连续问题的困难题】Python数分之Pandas训练,力扣,2173. 最多连胜
    学习:知识的初次邂逅复习:知识的温故知新练习:知识的实践应用目录一,原题力扣链接二,题干三,建表语句四,分析五,SQL解答六,验证七,知识点总结一,原题力扣链接.-力扣(LeetCode)二,题干表: Matches+-------------+------+|ColumnName|Type|+-------------+-----......
  • 面试经典 150 题:力扣88. 合并两个有序数组
    每周一道算法题启动题目【题目链接】【解法一】合并后排序排序后的数组自动省略0的数字,又学到了classSolution{public:voidmerge(vector<int>&nums1,intm,vector<int>&nums2,intn){//合并两个数组后排序for(inti=0;i<n;i++)......
  • LeetCode刷题日记之二叉树(二)
    目录前言左叶子之和找树左小角的值总结前言经过数模比赛的四天忙碌后博主继续开始LeetCode学习了,给大家分享学习心路的同时也是在不断勉励自己每天把自己的学的东西去进行一个产出记录,不足的地方欢迎大家批评指正,一起加油吧朋友们!......