豆包MarsCode算法题之字符串最短循环子串

字符串最短循环子串(第100道)

        题目链接

https://www.marscode.cn/practice/8eeee14o2vr7vn?problem_no=100

        题目描述

# 问题描述

- 输入一个字符串,判断其是否完全循环,若是循环的,输出最短的循环子串,否则输出空`""`

- 如输入 `abababab`,输出 `ab`;输入 `ab` 则输出 `""`

## 输入格式

- 合法字符串 如 `abcabcabcabc` `aaa`

## 输出格式

- 最短的循环子串 `"abc"` `"a"`

## 输入样例

- `"abcabcabcabc"`

## 输出样例

- `"abc"`

## 数据范围

测试数据集

       题目思路

        这道题我的思路十分暴力简单,如果大家有什么其他更好的方法也可以分享给我。

        首先,如果字符串时空串或者只有一个字符,就不存在什么循环之说,直接返回空串或原字符就行了。

        如果字符串不为空串,考虑到题目求的是循环子串,那原字符串最少也是由一个子串循环两次构成的,所以我们找子串的时候,只需要从原字符串的前半部分找就行了。

        接下来就很简单了,用一个for循环一次截取字符串,得到一个模版串,判断这个模版串是否符合要求就行了,因为题目要求最短,所以我们找到的第一个符合要求的模版串就是答案。

        接下来的重点就是如何判断这个模版串是否符合要求,是不是我们想要的模版串。

        第一步,先判断原字符串的长度是否能整除模版串的长度,如果不能的话,这个模版串肯定不可能是循环子串了,可以直接跳过。

        第二步,从原字符串中依次截取和模版串相同长度的子串,判断子串是否和模版串相等,若截取至原字符串末尾,所有子串都与模版串相等,那这个模版串就是我们要的最短循环子串了。如果出现一个不等,则不是。重新截取模版串重复上述操作。

         题目答案

public class No100 {
    public static void main(String[] args) {
        // Add your test cases here

        System.out.println(solution("abcabcabcabc").equals("abc"));
        //false
        System.out.println(solution("abababab").equals("abc"));
        //false
        System.out.println(solution("ab").equals("abc"));
        //true
        System.out.println(solution("abababab").equals("ab"));
    }
    public static String solution(String inp) {
        // Edit your code here
        //空串直接返回
        if(inp.length() <= 0){
            return "";
        }
        if (inp.length() == 1){
            return  inp;
        }
        //输入串的长度
        int inpL = inp.length();
        //结果
        String result = "";
        for(int i = 1;i< inpL / 2;i++){
            //依次截取字符串
            result = inp.substring(0,i);
            //获取临时模式串的长度
            int tempL = result.length();
            //判断是否整除,不整除一定不是完全循环
            if (inpL %  tempL != 0) {
                continue;
            }
            //标识是否是因为完全循环而退出
            boolean flag = true;
            //每次截取与模式串相同的长度进行匹配
            for(int start = tempL;start <= inpL -tempL;start += tempL ){
                //若出现任何一次不匹配,直接退出
                if (!inp.substring(start, start+tempL).equals(result)) {
                    flag = false;
                    break;
                }
            }
            //找到答案
            if (flag) {
                return result;
            }
        }
        return "";
    }

}

        总结感受

        这道题难度不大,很多人看一眼就有想法,也很容易就能做出来,但是想和做有时候确实可能会有点不一样。想法是个大概的思路,做却需要落实到具体细节,忽略一个细节都可能做错。        

        我做这道题的最大感受就是细节决定成败,还有想和做有一定的区别。一开始我的想法是这不就是一道KMP,还特地去重新学了一下KMP,但是真正做这道题的时候发现压根就不需要KMP,直接暴力做就行了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值