灯泡开关 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
    评论
好的,关于力扣刷题C++常用操作,我可以给你一些常见的操作和技巧: 1. 使用 STL 容器和算法库:STL(Standard Template Library)是 C++ 标准库中的一个重要组成部分,包含了许多常用的容器和算法。在力扣刷题中,使用 STL 可以大大提高代码的效率和可读性。例如,vector 可以用来存储动态数组,sort 可以用来排序等等。 2. 使用 auto 关键字:auto 关键字可以自动推导变量类型,可以减少代码量和提高可读性。例如,auto x = 1; 可以自动推导出 x 的类型为 int。 3. 使用 lambda 表达式:lambda 表达式是 C++11 中引入的一种匿名函数,可以方便地定义一些简单的函数对象。在力扣刷题中,使用 lambda 表达式可以简化代码,例如在 sort 函数中自定义比较函数。 4. 使用位运算:位运算是一种高效的运算方式,在力扣刷题中经常会用到。例如,左移运算符 << 可以用来计算 2 的幂次方,右移运算符 >> 可以用来除以 2 等等。 5. 使用递归:递归是一种常见的算法思想,在力扣刷题中也经常会用到。例如,二叉树的遍历、链表的反转等等。 6. 使用 STL 中的 priority_queue:priority_queue 是 STL 中的一个容器,可以用来实现堆。在力扣刷题中,使用 priority_queue 可以方便地实现一些需要维护最大值或最小值的算法。 7. 使用 STL 中的 unordered_map:unordered_map 是 STL 中的一个容器,可以用来实现哈希表。在力扣刷题中,使用 unordered_map 可以方便地实现一些需要快速查找和插入的算法。 8. 使用 STL 中的 string:string 是 STL 中的一个容器,可以用来存储字符串。在力扣刷题中,使用 string 可以方便地处理字符串相关的问题。 9. 注意边界条件:在力扣刷题中,边界条件往往是解决问题的关键。需要仔细分析题目,考虑各种边界情况,避免出现错误。 10. 注意间复杂度:在力扣刷题中,间复杂度往往是评判代码优劣的重要指标。需要仔细分析算法间复杂度,并尽可能优化代码。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值