leetcode题解-686. Repeated String Match && 38. Count and Say

原创 2017年11月13日 19:57:45

先看686这道题目:

Given two strings A and B, find the minimum number of times A has to be repeated such that B is a substring of it. If no such solution, return -1.

For example, with A = "abcd" and B = "cdabcdab".

Return 3, because by repeating A three times (“abcdabcdabcd”), B is a substring of it; and B is not a substring of A repeated two times ("abcdabcd").

Note:
The length of A and B will be between 1 and 10000.

给了两个字符串A和B,需要我们找出A重复多少次才能包含B这个子串,最简单的思路就是不断地重复A,直到A包含了B,或者A的长度已经足够大,即便再添加也没有什么意义,这时就说明A无法包含B,直接返回-1即可。很容易想到,当A的长度大于B时也就没有了添加的必要。代码如当下所示:

    public int repeatedStringMatch(String A, String B) {
        StringBuilder res = new StringBuilder(A);
        int count = 1;
        while(res.indexOf(B) < 0){
            //不断添加A,直到res的长度大于B,这时如果res包含B,则返回添加次数,否则说明无法包含,返回-1。
            //这里使用res的长度大于A+B的长度,是因为如果一开始A就比B大的话,不进行这一步判断会出错。比如A="abababaaba",B="aabaaba"
            if(res.length() - A.length() > B.length()) return -1;
            res.append(A);
            count ++;
        }
        return count;
    }

手上面这个例子启发,其实我们可以把情况分成两种,第一种是A长度大于B,那么直接使用A或者A+A判断是否包含B即可,然后如果A长度小于B,在使用上面的方法进行拼接判断,效率有很大提升,可以击败88%的用户:

    //88%
    public int repeatedStringMatch2(String A, String B) {
        if(A.length() > B.length()){
            if(A.contains(B))
                return 1;
            else if((A+A).contains(B))
                return 2;
        }
        StringBuilder res = new StringBuilder(A);
        int count = 1;
        while(res.indexOf(B) < 0){
            if(res.length() > B.length()) return -1;
            res.append(A);
            count ++;
        }
        return count;
    }

此外,我还在discuss里面发现一种效率更高的解法,可以击败99%的用户,代码如下所示:

    //99%
    public int repeatedStringMatch1(String A, String B) {
        int count = 1;
        int i = 0;
        for (int j = 0; j < B.length(); j++) {
            if (A.charAt(i) != B.charAt(j)) {
                if (count > 1) {       // already second time: no way to make B from A
                    return -1;
                }
                j = -1;    // try to match j's starting character with next i
            }

            i++;
            if (i == A.length()) {        // one more time of A
                if (j == B.length() - 1) {
                    break;
                }
                count++;
                i = 0;
                }
        }
        return count;
    }

接下来看第二道题目:

The count-and-say sequence is the sequence of integers with the first five terms as following:

1.     1
2.     11
3.     21
4.     1211
5.     111221
1 is read off as "one 1" or 11.
11 is read off as "two 1s" or 21.
21 is read off as "one 2, then one 1" or 1211.
Given an integer n, generate the nth term of the count-and-say sequence.

Note: Each term of the sequence of integers will be represented as a string.

Example 1:

Input: 1
Output: "1"
Example 2:

Input: 4
Output: "1211"

要获得第n个字符串的读法,而读法就是有m个数字n,就读mn,这样以此类推生成字符串。所以我们只需要递推生成字符串在获得其读法,然后一次生成读取即可。代码如下所示:

    //65%
    public String countAndSay(int n) {
        StringBuilder curr=new StringBuilder("1");
        StringBuilder prev;
        int count;
        char say;
        for (int i=1;i<n;i++){
            prev=curr;
            curr=new StringBuilder();
            //分别用于统计和记录数字的个数和数字
            count=1;
            say=prev.charAt(0);

            for (int j=1,len=prev.length();j<len;j++){
                if (prev.charAt(j)!=say){
                    curr.append(count).append(say);
                    count=1;
                    say=prev.charAt(j);
                }
                else count++;
            }
            curr.append(count).append(say);
        }
        return curr.toString();

    }
版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

LeetCode 38 Count and Say(C,C++,Java,Python)

Problem: The count-and-say sequence is the sequence of integers beginning as follows: 1, 11, 2...

[leetcode-38]Count and Say

自动生成序列的一道题,想起来昨天比赛里遇见的另一道题,问C_∞序列第N位是多少,昨天死磕到最后也就是写了个垃圾代码,然后输入N>10就不能运行,觉得这类题的要点是要开两个序列,一个生成另一个后,然后拷...

<LeetCode OJ> 38. Count and Say(测试案例或有错)

38. Count and Say My Submissions Question Total Accepted: 66138 Total Submissions: 243196 Diffic...

LeetCode 38. Count and Say

这是我在LeetCode中做到的第一道需要用到递归思想的题目,因为自己对递归掌握的不好,这里做个笔记:题目大意为我们有一个 Count-and-say 的字符串序列,他的第一个元素是‘1’,后一个元素...

LeetCode38——Count and Say

LeetCode38——Count and Say 上一题对我来说实在太凶残了,所以我还是缓缓先做38题好了。。。 题意: 可以理解为求一个数组的第n项,而这个数组的通项公式可以这样理解: 第...

【LEETCODE】38-Count and Say

The count-and-say sequence is the sequence of integers beginning as follows: 1, 11, 21, 1211, 111221...

leetcode38 Count and Say

package leetcode38; import java.util.ArrayList; /** * The count-and-say sequence is the sequence ...

LeetCode 38 Count and Say(计数与报数)

翻译计数报数序列按如下规律开始递增: 1,11,21,1211,111221,……1 读作“1个1”或11. 11 读作“2个1”或21. 21 读作“1个2,1个1”或1211.给定一个整数n,生成...
  • NoMasp
  • NoMasp
  • 2015年12月03日 10:32
  • 3878

LeetCode 38 Count and Say(字符串生成)

The count-and-say sequence is the sequence of integers with the first five terms as following: 1. ...

【leetcode c++】38 Count and Say

Count and Say The count-and-say sequence is the sequenceof integers beginning as follows: 1, 11, 2...
  • hqq39
  • hqq39
  • 2015年06月26日 22:40
  • 355
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:leetcode题解-686. Repeated String Match && 38. Count and Say
举报原因:
原因补充:

(最多只允许输入30个字)