灯泡开关 IV 力扣刷题

灯泡开关 IV


题目描述

房间中有 n 个灯泡,编号从 0 n-1 ,自左向右排成一行。最开始的时候,所有的灯泡都是着的。
请你设法使得灯泡的开关状态和 target 描述的状态一致,其中 target[i] 等于 1 i 个灯泡是开着的,等于 0 意味着第 i 个灯是关着的。

有一个开关可以用于翻转灯泡的状态,翻转操作定义如下:

  • 选择当前配置下的任意一个灯泡(下标为 i
  • 翻转下标从 i n-1 的每个灯泡

翻转时,如果灯泡的状态为 0 就变为 1,为 1 就变为 0
返回达成 target 描述的状态所需的 最少 翻转次数。


做题之前能快速的理解题意非常重要。先把题目意思看懂,看不懂也不要着急,结合下面的示例看题目意思,相信你能很快理解题目意思。

示例

题目要从一个"0000.."翻转成target,我们用逆向思维,从target翻转成"0000..",这样似乎简单一点。

示例1:

输入target = "10111"
输出3
解释初始配置 "00000".
从第 3 个灯泡(下标为 2)开始翻转 "00000" -> "00111"
从第 1 个灯泡(下标为 0)开始翻转 "00111" -> "11000"
从第 2 个灯泡(下标为 1)开始翻转 "11000" -> "10111"
至少需要翻转 3 次才能达成 target 描述的状态

示例2:

输入target = "101"
输出3
解释"000" -> "111" -> "100" -> "101".

示例 3:

输入target = "00000"
输出0

示例 4:

输入target = "001011101"
输出5


这题是有规律的

  1. "101""101111"的结果是一样的都是3,"101""100001"的结果也是一样都是3,这条规律,我想表达的意思是:在做这道题的时候,连在一起的1或连在一起的0都可以视为单个1或单个0。这里可以把这个步骤称为简化
  2. "10"的答案是2,"1010"的答案是4"101010"的答案是6,经过验证,想"1010...10"这种格式的答案就是其字符串长度
  3. "00101""101"结果一样都是3,开头的0可以全部去掉,但结尾的0就不一样了,"101""1010"答案不一样。

用以上规律解问题

我举个栗子:"0001011101101"

输入"0001011101101"
 
设置一个全局变量res=0存放翻转次数
简化"0001011101101"->"01010101“,简化步骤不会增加翻转次数。
根据规律3开头的0可以去掉:"01010101“->"1010101“,不会增加翻转次数。
"1010101“改成规律2的格式,①"1010101“->"1010100",翻转次数+1res++;
简化"1010100"->"101010",不会增加翻转次数;③根据规律3计算"101010"翻转成"000000"需要6步,翻转次数+6res+=6。最终答案就是7。
 
输出7

完整代码

class Solution {
public:
    int minFlips(string target) {
        int res=0;
        string s="";//存放简化完成的字符串
        
        //简化过程
        for(int i=0;i<target.length()-1;i++){
            if(target[i]!=target[i+1]){
                s+=target[i];
            }
        }
        s+=target[target.length()-1];
        //简化过程
        
        int n=s.length();//获取简化后的字符串长度
        cout<<s;
        if(s[0]=='0') n-=1;//如果开头为0,去掉开头的0,相当于字符串长度减一
        if(s[s.length()-1]=='1'){
            res+=1;//将结尾的1翻转成0,翻转次数+1,res++;
            n-=1;//这时,结尾有两个0,去掉结尾的一个0,相当于字符串长度减一
        }
        res+=n;
        return res;
    }
};

题目地址


运行

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值