首页 > 其他分享 >Leetcode3234. 统计 1 显著的字符串的数量

Leetcode3234. 统计 1 显著的字符串的数量

时间:2024-09-01 19:55:57浏览次数:5  
标签:子串 int Leetcode3234 显著 ans cnt1 cnt0 字符串 left

Every day a Leetcode

题目来源:3234. 统计 1 显著的字符串的数量

解法1:枚举左端点

注意到,如果子串中的 0 非常多,多到 0 的个数的平方比 1 的个数都要大,那么这样的子串必然不是 1 显著子串。

设 cnt0 为子串中的 0 的个数,cnt1 为子串中的 1 的个数,那么必须满足:cnt0 * cnt0 <= cnt1 <= n,所以子串中的 0 的个数不会超过 sqrt(n)。

在这里插入图片描述

代码:

/*
 * @lc app=leetcode.cn id=3234 lang=cpp
 *
 * [3234] 统计 1 显著的字符串的数量
 */

// @lc code=start
class Solution
{
public:
    int numberOfSubstrings(string s)
    {
        int n = s.length();
        vector<int> a;
        for (int i = 0; i < n; i++)
            if (s[i] == '0')
                a.push_back(i);

        int tot1 = n - a.size();
        a.push_back(n); // 哨兵

        int ans = 0, i = 0; // >= left 的第一个 0 的下标是 a[i]

        // 枚举子串左端点
        for (int left = 0; left < n; left++)
        { // 枚举子串有多少个 0
            // 枚举 0 的下标
            for (int k = i; k < a.size() - 1; k++)
            {
                int cnt0 = k - i + 1;
                if (cnt0 * cnt0 > tot1)
                    break;
                int p = a[k], q = a[k + 1];
                int cnt1 = a[k] - left - (k - i);
                if (cnt1 >= cnt0 * cnt0)
                {
                    // p, p+1, ..., q-1 都可以作为子串的右端点
                    ans += q - p;
                }
                else
                {
                    // cnt1 的个数少,补充 cnt0 * cnt0 - cnt1 个
                    ans += max(q - p - (cnt0 * cnt0 - cnt1), 0);
                }
            }
            // 没有 0 的情况
            if (s[left] == '0')
            {
                i++; // 这个 0 后面不会再枚举到了
            }
            else
            {
                ans += a[i] - left; // 不含 0 的子串个数
                tot1--;
            }
        }
        return ans;
    }
};
// @lc code=end

结果:

在这里插入图片描述

复杂度分析:

时间复杂度:O(n * sqrt(n)),其中 n 是字符串 s 的长度。

空间复杂度:O(n),其中 n 是字符串 s 的长度。

标签:子串,int,Leetcode3234,显著,ans,cnt1,cnt0,字符串,left
From: https://blog.csdn.net/ProgramNovice/article/details/141689740

相关文章

  • Java:有效括号字符串验证器
    Java实现的有效括号字符串验证器引言在编程中,经常需要验证一组字符串中的括号是否正确配对。例如,检查一段代码或表达式中的圆括号、方括号和花括号是否成对出现。这类问题不仅在编程语言解析器中非常重要,也是许多软件开发场景中的基础需求。本文将介绍一种基于Java语言实......
  • 【3.10】贪心算法-找出对应 LCP 矩阵的字符串
    一、题目对任一由n个小写英文字母组成的字符串word,我们可以定义一个nxn的矩阵,并满足:lcp[i][j]等于子字符串 word[i,...,n-1]和word[j,...,n-1]之间的最长公共前缀的长度。给你一个nxn的矩阵lcp。返回与lcp对应的、按字典序最小的字符串 word。如果......
  • 高级字符串算法
    目录最长公共子串/子序列最长公共子串算法步骤代码示例复杂度分析最长公共子序列算法步骤代码示例复杂度分析正则表达式匹配正则表达式语法代码示例NFA与DFA在正则表达式匹配中的应用NFA(非确定性有限自动机)DFA(确定性有限自动机)NFA与DFA的比较字符串编辑距离(Le......
  • stdio.h及字符串输入输出
    这里只简单介绍常用的C语言常见的输入输出及字符串的输入输出,可以作为常用C语言字符串的速记收藏。#include<stdio.h>scanf //与空格,tab键及换行就阻断缓冲区printf //格式输入输出gets(数组名) //直到遇到换行键停止chararr[n];gets(arr);puts(数组名) //......
  • 【C】关于字符串与字符串函数de一些小练习
    关于字符串与字符串函数de小练习1.字符串中的最大数你需要找出十个数中最大的哪一个,但不幸的是因为一些故障,一些小写字母随机的插入了这是个数字。请忽视这十个字符串中无意义的小写字母,输出这十个数字中最大的那一个,以及它来自于哪一个字符串。输入:"a3a2dsa3f4fsa5dg......
  • HJ19 简单错误记录 || 字符串模拟
    就是字符串模拟和处理。最大的问题就是题面题意写得真的挺模糊的,好多地方有点表意不明。。1#include<bits/stdc++.h>2usingnamespacestd;3constintmaxn=110;4chara[maxn][maxn];5intb[maxn],num_qc=0,cnt[maxn],ans[maxn],num_ans=0;6boolfg[maxn],f[ma......
  • 字符串的处理
    消除换行符if(str[i]=='\n')str[i]='\0';scanf和cin会读取空格,而fgets不会gets_s许多编译器不支持,不建议用charstr[N]; if(fgets(str,sizeof(str),stdin)==NULL) { return1; }格式化输入输出sprintf:功能:sprintf用于将格式化的数据输出到一个字符串......
  • sha-256算法,生成固定长度的字符串
    SHA-256(安全哈希算法256位)是一种广泛使用的加密哈希函数,它会将输入的任意大小的数据转换为固定长度的256位(32字节)哈希值。SHA-256是SHA-2系列算法的一部分,由美国国家安全局(NSA)设计,并由美国国家标准与技术研究院(NIST)发布。SHA-256的主要特点包括:固定长度输出:无论输入数据的......
  • JavaScript 的模板字符串
    字符串插值JavaScript中使用反引号`包裹的字符串叫模板字符串(templateliterals)。人们常用它拼接变量和字符串,即所谓的字符串插值(stringinterpolation)。在使用字符串插值时,使用${}包裹变量或表达式,它是变量的占位符。多行文本模板字符串支持多行文本(multi-linestr......
  • 关于java输入字符串的一些问题
    最近自学java,学到了Scanner类这块,我想着测试一下输入,遇到了个问题,我想要输入两个字符串,但是我输入一个字符串后程序就停止运行了,有点疑惑,我的代码如下s1=scan.next();System.out.print(s1);s2=scan.nextLine();System.out.print(s2);结果就是只能输出s1,然后我就想起来这......