[leetcode]696. Count Binary Substrings

问题:Give a string s, count the number of non-empty (contiguous) substrings that have the same number of 0's and 1's, and all the 0's and all the 1's in these substrings are grouped consecutively.

Substrings that occur multiple times are counted the number of times they occur.


题目的大致意思是说:给定一个只包含‘0’和‘1’字符串让你找出这个字符串的子串这个子串必须有相同多的‘0’和‘1’,而且‘0’和‘1’必须相连接起来,让你返回所有符合条件的子串数量。比如:给你一个字符串是“0011000”,那所有符合题中的子串按照顺序应该是:“0011”,“01”,“1100”,“10”一共四个。

大致思考一下:问题的关键在于如何找出分界线,以及分界线两边‘0’和‘1’的个数分别是多少。

    public int countBinarySubstrings(String s) {
        int first = 0;
        int second = 0;
        int sum = 0;
        ArrayList<Character> qu = new ArrayList<Character>();
        for(int i = 0;i<s.length();i++){
        	if(i==0){
        		qu.add(s.charAt(i));
        	}else{
        		char a = qu.get(qu.size()-1);
        		if(first == 0 && second==0){
        			if(a == s.charAt(i)){
        				qu.add(s.charAt(i));
        			}else{
        				first=i;
        				qu.add(s.charAt(i));
        			}
        		}else if(first != 0 && second==0){
        			if(a == s.charAt(i)){
        				qu.add(s.charAt(i));
        			}else{
        				second=qu.size();
        				qu.add(s.charAt(i));
        				sum+=Math.min(first, second-first);
            			for(int j=0;j<first;j++){
            				qu.remove(0);
            			}
            			first = qu.size()-1;
            			second = 0;
        			}
        		}
        	}
        }
        second=qu.size();
        sum+=Math.min(first, second-first);
        return  sum;		
    }


提交后出现timeout,说明代码没有错误,只是计算过于复杂导致的超时。于是又重新调整一下自己的思维,对于一个给定的字符串“0011000”,将其表示成为[2,2,3]。问题不就成为:求数组中两个相邻数字最小的那个的和了么。


    public int countBinarySubstrings(String s) {
        int sum = 0;
        int [] arr = new int[s.length()];
        arr[0]=1;
        int j =0;
        for(int i = 1;i<s.length();i++){
        	if(s.charAt(i)==s.charAt(i-1)){
        		arr[j]++;
        	}else{
        		j++;
        		arr[j] = 1;
        	}
        }
        for(int i=0;i+1<arr.length;i++){
        	sum+=Math.min(arr[i], arr[i+1]);
        }
        return  sum;		
    }
OK,这次的代码可以通过提交,再回头看看,我们完全可以消除arr这个中间数组,直接计算不就行了。

    public int countBinarySubstrings(String s) {
        int sum = 0;
        int count =1;
        int counted=0;
        for(int i = 1;i<s.length();i++){
        	if(s.charAt(i)==s.charAt(i-1)){
        		count++;
        	}else{
        		sum+=Math.min(count,counted);
        		counted = count;
        		count = 1;
        	}
        }
        return  sum+Math.min(count,counted);		
    }

这样一来复杂度仅为O(n),执行速度提高不少。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值