【第四章 字符串part02】

news/2024/7/23 9:35:19 标签: leetcode, 算法, java

28. 实现 strStr()

题目

java">public  int strStr(String s, String p) {
    // 输入:haystack = "sa", needle = "ss"
    //输出:0
    // bf算法
    int sLen = s.length();
    int pLen = p.length();
    for (int i = 0; i < sLen-pLen+1; i++) {
        if(isEqual(s.substring(i,i+pLen),p)){
            return i;
        }
    }
    return -1;
}

private boolean isEqual(String str, String p) {
    for (int i = 0; i < str.length(); i++) {
        if (str.charAt(i) != p.charAt(i)) {
            return false;
        }
    }
    return true;
}
java">public  int strStr(String s, String p) {
        // 输入:haystack = "aaaaabab", needle = "aaab"
        // 输出:0
        // kmp算法
        // 构建next数组
        int now = 0;
        int x = 1;
        int[] next = new int[p.length()];
        next[0] = 0;
        while (x < p.length()) {
            // aadca....abc
            //hello
            if (p.charAt(now) == p.charAt(x)) {
                now++;
                next[x] = now;
                x++;
            }
            // abcabd...abcabc
            // 不相等则缩小now,缩小到next[now-1]
            //
            else if (now != 0) {
                now = next[now-1];
            }
            // now为0
            else {
                next[x] = 0;
                x += 1;
            }
        }

        // 匹配
        // 利用next数组来减少匹配次数
        // aaaa ab aaab
        int tar = 0;
        int pos = 0;
        int sLen = s.length();
        int pLen = p.length();
        while(tar < sLen) {
            if (s.charAt(tar) == p.charAt(pos)) {
                if (pos == pLen-1) return tar-pos;
                tar++;
                pos++;
            }
            // 若不相等,则移动pos到next[pos-1]
            // tar在刚失配的地方
            else if (pos != 0) {
                pos = next[pos-1];
            }
            // 若第一位失配,则移动tar指针
            else {
                tar++;
            }

        }
        return -1;
    }

459.重复的子字符串

题目

  • 超时
java">private static boolean isEqual(String str, String p) {
    if (str.length() != p.length()) return false;
    for (int i = 0; i < str.length(); i++) {
        if (str.charAt(i) != p.charAt(i)) {
            return false;
        }
    }
    return true;
}

public static boolean repeatedSubstringPattern(String s) {
    // 输入: s = "abab"
    //输出: true
    //解释: 可由子串 "ab" 重复两次构成。
    // 1. 若为奇数,则截取前k个(1,2,3,...n/2)
    //acdacd
    //acd
    // 2. 若为偶数,则子串
    // ababab
    int k = 1;
    int group;
    while (k <= s.length()/2) {
        StringBuilder sb = new StringBuilder();
        String p = s.substring(0, k);

        group = s.length()/p.length();

        for (int j = 0; j < group; j++) {
            sb.append(p);
        }
        System.out.println("group:"+group);
        System.out.println("s:"+s+",p:"+sb.toString());
        if (isEqual(s,sb.toString())) {
            return true;
        }
        k++;
    }
    return false;
}
  • KMP的next数组方法
  • 前面方法超时,因此我们思考,要找重复子字符串,与前缀后缀匹配相关,因此想到next数组
  • 通过观察next数组,我们可以发现,若len可以被len-next[len-1]的值整除,则说明都是由重复子字符串构成。

证明

  • 假设字符串s使用多个重复子串构成(这个子串是最小重复单位),重复出现的子字符串长度是x,所以s是由n * x组成。
  • 因为字符串s的最长相同前后缀的的长度一定是不包含s本身,所以 最长相同前后缀长度必然是m * x,而且 n - m = 1,(这里如果不懂,看上面的推理)
  • 所以如果 nx % (n - m)x = 0,就可以判定有重复出现的子字符串。
java">public static boolean repeatedSubstringPattern(String s) {
    int now = 0;
    int x = 1;
    int[] next = new int[s.length()];
    next[0] = 0;
    while (x < s.length()) {
        // aadca....abc
        //hello
        if (s.charAt(now) == s.charAt(x)) {
            now++;
            next[x] = now;
            x++;
        }
        // abcabd...abcabc
        // 不相等则缩小now,缩小到next[now-1]
        //
        else if (now != 0) {
            now = next[now-1];
        }
        // now为0
        else {
            next[x] = 0;
            x += 1;
        }
    }
    // 找到第一个非0下标,加上最后一个的值 若为len,则true
    if (next[s.length() - 1] != 0 && s.length() % (s.length() - (next[s.length() - 1])) == 0) {
        return true;
    }
    return false;
}

http://www.niftyadmin.cn/n/4950516.html

相关文章

代码随想录 (二)链表

链表 二 移除链表元素 1 没有头结点 /*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode() : val(0), next(nullptr) {}* ListNode(int x) : val(x), next(nullptr) {}* ListNode(int x, ListNode *next)…

html流光按钮

出处bilibili猫咪爱狗 <!DOCTYPE html> <html><head><style>body {/*内容居中&#xff0c;背景色*/height: 100vh;display: flex;justify-content: center; align-items: center;background-color: #000;}a { /*水平垂直居中*/position: re…

智能可穿戴:探索未来的无人之境

智能可穿戴&#xff1a;探索未来的无人之境 目录 引言智能可穿戴的历史与现状智能可穿戴的下一个蓝海&#xff1a;概念与理论市场展望&#xff1a;无人之境技术挑战与机遇结论 1. 引言 在科技的洪流中&#xff0c;智能可穿戴设备脱颖而出&#xff0c;以其便捷性、个性化和智…

Java Map、JSONObject、实体类互转

文章目录 前言Map、JSONObject、实体类互转 前言 使用库 com.alibaba.fastjson2&#xff0c;可完成大部分JSON转换操作。 详情参考文章: Java FASTJSON2 一个性能极致并且简单易用的JSON库 Map、JSONObject、实体类互转 import com.alibaba.fastjson2.JSON; import com.alib…

探索短视频小程序/小年糕

短视频小程序的兴起&#xff0c;为创作者提供了一个全新的平台&#xff0c;让他们能够以更专业的方式展现自己的作品。这种创作形式不仅要求作品内容足够精彩还需要有深度的思考和逻辑性的呈现。本文将探索短视频小程序的专业与深度的创作之道&#xff0c;帮助创作者更好地发挥…

Linux—LVM基础

Linux—LVM 一、什么是LVM二、LVM名词解释三、LVM的写入模式四、LVM的工作原理五、LVM的优缺点六、创建PV/VG/LV的方法补充说明 一、什么是LVM LVM&#xff08;Logical Volume Manager&#xff09;&#xff0c;即逻辑卷管理&#xff0c;是Linux环境下对磁盘分区进行管理的一种…

C语言,malloc使用规范

malloc 是 C 语言中用于分配内存的函数。它的名称是“memory allocation”的缩写。malloc 是在 <stdlib.h> 头文件中定义的。 malloc 的基本语法是&#xff1a; void* malloc(size_t size); 其中 size_t是要分配的字节数。如果分配成功&#xff0c;malloc返回一个指向分配…

eNSP 打开警告:请将eNSP相关应用程序添加到windows firewall的允许程序列表,并允许其在公用网络上运行!

文章目录 1 警告截图2 解决办法 1 警告截图 2 解决办法 思路&#xff1a;按照警告的提示信息&#xff0c;将 eNSP 相关应用添加到 windows firewall&#xff08;防火墙&#xff09;的允许程序列表&#xff0c;并允许其在公用网络上运行&#xff01;此处以 Win 10 为例