java数据结构与算法刷题-----LeetCode696. 计数二进制子串

java数据结构与算法刷题目录(剑指Offer、LeetCode、ACM)-----主目录-----持续更新(进不去说明我没写完):https://blog.csdn.net/grd_java/article/details/123063846

在这里插入图片描述

1. 法一:时间复杂度O(n).空间复杂度O(n)

解题思路

因为字符串只有0和1两个字符,所以我们可以对字符串进行分组

  1. 假设有00011100000111这样一个字符串,我们记录每次字符出现次数
  2. 0出现3次,1出现3次,0有出现5次,1又出现3次
  3. 题目要求我们只要0和1相邻,然后数量一致即可

两个相邻的连续串,比如0001111,这里0有3个,1有4个,题目要求连续且0和1个数相等
那么只能000111.0011,01.正好可以由3种不同0的数量,组成答案。也就是谁少听谁的

代码

在这里插入图片描述

class Solution {
    public int countBinarySubstrings(String s) {
        List<Integer> counts = new ArrayList<Integer>();//分组
        int ptr = 0, n = s.length();//ptr为下标,
        while(ptr < n){//如果还有字符串可遍历
            char c = s.charAt(ptr);//获取当前字符
            int count = 0;//记录当前字符连续出现的个数
            while(ptr < n && s.charAt(ptr) == c){//如果当前字符连续出现
                ptr++;count++;//下标后移,count++
            }
            counts.add(count);//当字符连续性中断时,记录当前字符出现次数
        }
        int ans = 0;//输出答案
        //两个相邻的连续串,比如0001111,这里0有3个,1有4个,题目要求连续且0和1个数相等
        //那么只能000111.0011,01.正好可以由3种不同0的数量,组成答案。也就是谁少听谁的
        for(int i = 1;i<counts.size();i++)
            ans += Math.min(counts.get(i), counts.get(i-1));
        return ans;
    }
    
}

2. 法二:时间复杂度O(n).空间复杂度O(1)

解题思路

法一使用了额外的List存储字符串0和1的分组信息。接下来我们将其优化掉,用一个滚动变量来代替List

代码

在这里插入图片描述

class Solution {
    public int countBinarySubstrings(String s) {
        int ptr = 0, n = s.length(), last = 0, ans = 0;//ptr为下标,last为滚动变量,ans保存答案
        while (ptr < n) {//只要有字符可遍历就继续
            char c = s.charAt(ptr);//获取当前字符
            int count = 0;//对本次字符,进行连续个数统计
            while (ptr < n && s.charAt(ptr) == c) {
                ++ptr;
                ++count;
            }
            ans += Math.min(count, last);//ans直接进行处理。而不是存储到List中最后统一处理
            last = count;//滚动变量继续滚动
        }
        return ans;
    }
}

2. 法三:时间复杂度O(n).空间复杂度O(1)

解题思路

对法二进一步优化流程,每次循环,少了很多条件判断,实际意义不大,仅仅能快个1到2毫秒而已。但是如果你追求超越100%的其它用户,可以尝试。

代码

在这里插入图片描述

class Solution {
    public int countBinarySubstrings(String s) {
        char a[] = s.toCharArray();//获取数组
        char last = a[0];//当前分组的第一个字符
        int preCount = 0, curCount = 1;//preCount表示上一个字符出现的次数,curCount的当前字符last的出现次数
        int res = 0;//res保存最终答案
        for (int i = 1, n = s.length(); i < n; i++) {//遍历字符串
            char c = a[i];//获取字符
            if (last != c) {//如果当前字符和第一个last保存的字符不一致了,就说明当前分组统计完成
                res += Math.min(preCount, curCount);//preCount和curCount谁小听谁的
                preCount = curCount;//preCount变为当前curCount,理解为后移操作
                curCount = 0;//cur重新计算下一个last的出现次数
                last = c;//last后移
            }
            curCount++;//如果当前字符和last一致,cur++
        }
        res += Math.min(preCount, curCount);//最终还得额外保存一次
        return res;
    }
}    
1.1 单项选择 1. 数据结构是一门研究非数值计算的程序设计问中,数据元素的① 、数据信息在计算机中的② 以及一组相关的运算等的课程。 ① A.操作对象   B.计算方法  C.逻辑结构  D.数据映象 ② A.存储结构 B.关系 C.运算 D.算法 2. 数据结构DS(Data Struct)可以被形式地定义为DS=(D,R),其中D是① 的有限集合,R是D上的② 有限集合。 ① A.算法 B.数据元素 C.数据操作 D.数据对象 ② A.操作 B.映象 C.存储 D.关系 3.数据结构中,从逻辑上可以把数据结构分成 。 A.动态结构和静态结构 B.紧凑结构和非紧凑结构 C.线性结构和非线性结构 D.内部结构和外部结构 4. 算法分析的目的是① ,算法分析的两个主要方面是② 。 ① A. 找出数据结构的合理性 B. 研究算法中的输入和输出的关系 C. 分析算法的效率以求改进 D. 分析算法的易懂性和文档性 ② A. 空间复杂性和时间复杂性 B. 正确性和简明性 C. 可读性和文档性 D. 数据复杂性和程序复杂性 5. 计算机算法指的是① ,它必具备输入、输出和② 等五个特性。 ① A. 计算方法 B. 排序方法 C. 解决问的有限运算序列 D. 调度方法 ② A. 可行性、可移植性和可扩充性 B. 可行性、确定性和有穷性 C. 确定性、有穷性和稳定性 D. 易读性、稳定性和安全性 1.2 填空(将正确的答案填在相应的空中) 1. 数据逻辑结构包括 、 、 和 四种类型,树形结构和图形结构合称为 。 2. 在线性结构中,第一个结点 前驱结点,其余每个结点有且只有 个前驱结点;最后一个结点 后续结点,其余每个结点有且只有 个后续结点。 3. 在树形结构中,树根结点没有 结点,其余每个结点有且只有 个直接前驱结点,叶子结点没有 结点,其余每个结点的直接后续结点可以 。 4. 在图形结构中,每个结点的前驱结点数和后续结点数可以 。 5. 线性结构中元素之间存在 关系,树形结构中元素之间存在 关系,图形结构中元素之间存在 关系。 6. 算法的五个重要特性是__ __ , __ __ , ___ _ , __ __ , _ ___。 7. 分析下面算法(程序段),给出最大语句频度 ,该算法的时间复杂度是__ __。 for (i=0;i<n;i++) for (j=0;j<n; j++) A[i][j]=0; 8. 分析下面算法(程序段),给出最大语句频度 ,该算法的时间复杂度是__ __。 for (i=0;i<n;i++) for (j=0; j<i; j++) A[i][j]=0; 9. 分析下面算法(程序段),给出最大语句频度 ,该算法的时间复杂度是__ __。 s=0; for (i=0;i<n;i++) for (j=0;j<n;j++) for (k=0;k<n;k++) s=s+B[i][j][k]; sum=s; 10. 分析下面算法(程序段)给出最大语句频度 ,该算法的时间复杂度是__ __。 int i=0,s=0; while (s<n) { i++; s+=i; //s=s+i } 11. 分析下面算法(程序段)给出最大语句频度 ,该算法的时间复杂度是__ __。 i=1; while (i<=n) i=i*2;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ydenergy_殷志鹏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值