LeetCode 6035. 选择建筑的方案数

题目链接:

力扣icon-default.png?t=M276https://leetcode-cn.com/problems/number-of-ways-to-select-buildings/

【前缀和】统计连续的0和1的个数,符合题意的方案无非就是010,101这两种,我们以中间的数字为基准来遍历统计的个数,以010为例:以1为基准,当前所在位置1的个数*前面0的个数*后面0的个数。

class Solution:
    def numberOfWays(self, s: str) -> int:
        n, t, ans = len(s), 0, 0
        c = s[0]
        cnt = []
        for i in range(n):
            if s[i] == c:
                t += 1
            else:
                cnt.append(t)
                t = 1
                c = s[i]
        cnt.append(t)
        m = len(cnt)
        if m < 3:
            return 0
        sum0, sum1 = 0, 0
        for i in range(m):
            if i % 2 == 0:
                sum0 += cnt[i]
            else:
                sum1 += cnt[i]
        i = 1
        pre = cnt[0]
        sum0 -= pre
        while i + 1 < m:
            ans += pre * cnt[i] * sum0
            pre += cnt[i + 1]
            sum0 -= cnt[i + 1]
            i += 2
        i = 2
        pre = cnt[1]
        sum1 -= pre
        while i + 1 < m:
            ans += pre * cnt[i] * sum1
            pre += cnt[i + 1]
            sum1 -= cnt[i + 1]
            i += 2
        return ans

【Java版】

class Solution {
    public long numberOfWays(String s) {
        List<Integer> cnt = new ArrayList<>();
        int n = s.length(), i, t = 0;
        long ans = 0;
        char c, pre = s.charAt(0);
        for(i = 0; i < n; i++){
            c = s.charAt(i);
            if(c == pre){
                t++;
            }else{
                cnt.add(t);
                t = 1;
                pre = c;
            }
        }
        cnt.add(t);
        int sum0 = 0, sum1 = 0;
        n = cnt.size();
        if(n < 3) return 0;
        for(i = 0; i < n; i++){
            if(i % 2 == 0) sum0 += cnt.get(i);
            else sum1 += cnt.get(i);
        }
        i = 1;
        int p = cnt.get(0);
        sum0 -= p;
        while(i + 1 < n){
            ans += (long)p * cnt.get(i) * sum0;
            p += cnt.get(i + 1);
            sum0 -= cnt.get(i + 1);
            i += 2;
        }
        i = 2;
        p = cnt.get(1);
        sum1 -= p;
        while(i + 1 < n){
            ans += (long)p * cnt.get(i) * sum1;
            p += cnt.get(i + 1);
            sum1 -= cnt.get(i + 1);
            i += 2;
        }
        return ans;
    }
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值