首页 > 其他分享 >力扣最热一百题——最长公共前缀

力扣最热一百题——最长公共前缀

时间:2024-09-22 11:22:41浏览次数:3  
标签:前缀 strs 最热 力扣 prefix 数组 公共 字符串

目录

题目链接:14. 最长公共前缀 - 力扣(LeetCode)

题目描述

示例

提示:

解法一:逐步缩减前缀

Java写法:

运行时间

C++写法:

运行时间

时间复杂度和空间复杂度

解法二:字典序排序

什么是字典序?

为什么通过字典序排序之后的首位字符串就可以找到最长公共前缀?

举例说明:

Java写法:

运行时间

C++写法:

运行时间

时间复杂度和空间复杂度

总结


题目链接:14. 最长公共前缀 - 力扣(LeetCode)

注:下述题目描述和示例均来自力扣

题目描述

编写一个函数来查找字符串数组中的最长公共前缀。

如果不存在公共前缀,返回空字符串 ""

示例

示例 1:

输入:strs = ["flower","flow","flight"]
输出:"fl"

示例 2:

输入:strs = ["dog","racecar","car"]
输出:""
解释:输入不存在公共前缀。

提示:

  • 1 <= strs.length <= 200
  • 0 <= strs[i].length <= 200
  • strs[i] 仅由小写英文字母组成


解法一:逐步缩减前缀

这段代码的实现思路是基于一个假设开始的:它假设数组中的第一个字符串(strs[0])是最长的公共前缀。然后,它遍历数组中的每个后续字符串(从strs[1]开始),并检查当前假设的公共前缀(prefix)是否仍然是这些字符串的前缀。

具体实现步骤如下:

  1. 处理空数组:首先,它检查传入的字符串数组strs是否为空或长度为0。如果是,那么没有公共前缀,直接返回空字符串。

  2. 初始化公共前缀:然后,它将数组中的第一个字符串(strs[0])作为初始的公共前缀(prefix)。

  3. 遍历数组:接下来,它使用一个for循环遍历数组中的每个后续字符串(从索引1开始,即strs[1]strs[strs.length - 1])。

  4. 检查前缀:对于每个后续字符串,它使用indexOf方法检查当前假设的公共前缀(prefix)是否是该字符串的前缀(即indexOf(prefix)是否返回0)。

    • 如果不是前缀(indexOf(prefix)不等于0),则进入一个while循环,逐步缩短prefix(通过移除prefix的最后一个字符),直到prefix成为该字符串的前缀或prefix变为空字符串。
    • 如果在缩短prefix的过程中prefix变为空字符串,那么说明没有公共前缀,函数返回空字符串。
  5. 返回结果:如果遍历完所有字符串后都没有返回空字符串,那么说明prefix就是所有字符串的最长公共前缀,函数返回prefix

       当然了既然把这个方法放在第一位那么就是可以优化,这个实现虽然可以正确找到最长公共前缀,但它在有一些情况下可能不是最高效的。特别是,当prefix被缩短时,它可能会多次检查同一个较短的prefix是否是某个字符串的前缀,这是肯定是多余的了。但是由于力扣的测试用例说实话还是挺友善的,所以实现起来的速度还是挺快的。

Java写法:

class Solution {
    public String longestCommonPrefix(String[] strs) {
        // 处理空数组
        if (strs == null || strs.length == 0) {
            return "";  
        }

        // 假设第一个字符串是最长公共前缀
        String prefix = strs[0]; 

        for (int i = 1; i < strs.length; i++) {

            // 如果当前字符串不以 prefix 开头
            while (strs[i].indexOf(prefix) != 0) {  
                // 缩短前缀
                prefix = prefix.substring(0, prefix.length() - 1);  
                // 如果前缀为空,返回空字符串
                if (prefix.isEmpty()) {
                    return "";  
                }
            }
        }
        // 返回找到的最长公共前缀
        return prefix;  
    }
}

运行时间

C++写法:

class Solution {
public:
    string longestCommonPrefix(vector<string>& strs) {
        // 处理空数组
        if (strs.empty()) {
            return "";  
        }

        // 假设第一个字符串是最长公共前缀
        string prefix = strs[0];

        // 从第二个字符串开始遍历
        for (int i = 1; i < strs.size(); i++) {
            // 如果当前字符串不以 prefix 开头
            while (strs[i].find(prefix) != 0) {  
                // 缩短前缀
                prefix = prefix.substr(0, prefix.size() - 1);
                // 如果前缀为空,返回空字符串
                if (prefix.empty()) {
                    return "";  
                }
            }
        }

        // 返回找到的最长公共前缀
        return prefix;
    }
};

运行时间

 

时间复杂度和空间复杂度

 




解法二:字典序排序

什么是字典序?

        字典序(Lexicographical Order)是一种字符串排序方式,这个方式类似于我们在字典中查找单词时候的顺序。字符串根据其字符的排列方式,按照字母表的顺序进行排序。

        例如,对于字符串 ["apple", "banana", "grape", "orange"],按照字典序排序的结果是:

  • apple
  • banana
  • grape
  • orange

        在字典序中,首先比较字符串的首字母,如果首字母相同,就比较第二个字母,依此类推。对于长度不同的字符串,如果前面几位都相同的话,那么就让较短的字符串排在前面。例如:

  • "abc" 排在 "abcd" 前面。

为什么通过字典序排序之后的首位字符串就可以找到最长公共前缀?

        通过字典序排序后,数组的第一个字符串和最后一个字符串之间的公共前缀,实际上也是所有字符串之间的最长公共前缀。这是因为:

  1. 字典序是按照字符的逐个比较进行的,因此字典序排序后的第一个字符串和最后一个字符串在整个数组中具有最小和最大的“字母顺序”。

  2. 最小和最大的字符串之间的差异最大,换句话说,它们在前面相同的部分已经是所有字符串中公共前缀的最长部分。它们的不同部分意味着,其他字符串不可能有更长的公共前缀。

  3. 公共前缀只会出现在最小和最大字符串的前缀部分,因为如果最小字符串和最大字符串的前缀部分相同,其他字符串在这部分也一定相同。

举例说明:

假设字符串数组是:["flower", "flow", "flight"],那么排序后结果就是:

  • "flight"
  • "flow"
  • "flower"

        比较排序后的第一个字符串 "flight" 和最后一个字符串 "flower",它们的最长公共前缀是 "fl"。因此,我们只需要比较第一个和最后一个字符串,酱紫找到它们的公共前缀就可以确定整个数组的最长公共前缀,因为其他字符串在这部分的前缀也必然是相同的。

Java写法:

import java.util.Arrays;

class Solution {
    public String longestCommonPrefix(String[] strs) {
        // 获取数组长度
        int len = strs.length;
        
        // 如果数组为空,返回空字符串
        if (len == 0) {
            return "";
        }
        
        // 对字符串数组进行字典序排序
        Arrays.sort(strs);
        
        // 定义结果字符串,使用StringBuilder便于拼接字符串
        StringBuilder res = new StringBuilder();
        
        // 比较排序后第一个和最后一个字符串的相似部分
        for (int i = 0; i < strs[0].length() && i < strs[len - 1].length(); i++) {
            // 如果当前字符相同,加入结果
            if (strs[0].charAt(i) == strs[len - 1].charAt(i)) {
                res.append(strs[0].charAt(i));
            } else {
                // 如果不相同,结束循环
                break;
            }
        }
        
        // 返回结果
        return res.toString();
    }
}

运行时间

C++写法:

class Solution {
public:
    string longestCommonPrefix(vector<string>& strs) {
        // 数组长度
        int len = strs.size();
        // 对这个字符串数组进行字典序排序
        sort(strs.begin(), strs.end());
        // 定义出res
        string res = "";
        // 找这俩的相似点
        for(int i = 0; i < strs[0].size() && i < strs[len - 1].size(); i++){
            // 一样就加进去
            if(strs[0][i] == strs[len - 1][i]){
                // 拼接答案
                res += strs[0][i];
            }else{
                // 不一样就说明到头了直接返回
                break;
            }
        }
        return res;
    }
};

运行时间

时间复杂度和空间复杂度

 


总结

        哇塞是不是又懂了一个操作的方法,这个字典序的思路简直是天才好吧

那么大家加油!!!

标签:前缀,strs,最热,力扣,prefix,数组,公共,字符串
From: https://blog.csdn.net/DDDDWJDDDD/article/details/142433354

相关文章

  • 2024.09.22 力扣刷题 Z字形变换
    题目:将一个给定字符串s根据给定的行数numRows,以从上往下、从左到右进行Z字形排列。比如输入字符串为"PAYPALISHIRING"行数为3时,排列如下:PAHNAPLSIIGYIR之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:"PAHNAPLSIIGYIR"。请你实......
  • 【数据结构-差分】【hard】力扣995. K 连续位的最小翻转次数
    给定一个二进制数组nums和一个整数k。k位翻转就是从nums中选择一个长度为k的子数组,同时把子数组中的每一个0都改成1,把子数组中的每一个1都改成0。返回数组中不存在0所需的最小k位翻转次数。如果不可能,则返回-1。子数组是数组的连续部分。示......
  • 【力扣 | SQL题 | 每日三题】力扣175, 176, 181
    1.力扣175:组合两个表1.1题目:表: Person+-------------+---------+|列名|类型|+-------------+---------+|PersonId|int||FirstName|varchar||LastName|varchar|+-------------+---------+personId是该表的主键(具有唯一......
  • 【数据结构与算法 | 灵神题单 | 栈基础篇】力扣1441, 844, 682
    1.力扣1441:用栈操作构建数组1.1题目:给你一个数组 target 和一个整数 n。每次迭代,需要从  list={1,2,3...,n} 中依次读取一个数字。请使用下述操作来构建目标数组 target :"Push":从 list 中读取一个新元素,并将其推入数组中。"Pop":删除数组中的最后一......
  • 远程控制软件哪个好用?2024年最热门的5款电脑远程控制软件,亲测好用
    远程控制软件哪个好用?相信这是许多企业面临的一大难题。特别是在需要同时管理多台电脑时,一款高效、稳定的远程控制软件更是显得尤为重要。今天,我们就来盘点2024年最热门的5款电脑远程控制软件,看看它们是如何走进大众心里的!1. TeamViewerTeamViewer是全球知名的远程控制工具......
  • 力扣最热一百题——除自身以外数组的乘积
    目录题目链接:238.除自身以外数组的乘积-力扣(LeetCode)题目描述示例提示:解法一:左右数组(小型动态规划)实现思路Java写法:运行时间C++写法:运行时间时间复杂度以及空间复杂度总结题目链接:238.除自身以外数组的乘积-力扣(LeetCode)注:下述题目描述和示例均来自力扣......
  • 力扣最热一百题——搜索二维矩阵
    目录题目链接:240.搜索二维矩阵II-力扣(LeetCode)题目描述解法一:暴力不解释Java写法:运行时间C++写法:运行时间时间复杂度以及空间复杂度 解法二:利用自带的大小关系进行Z型走位Java写法:运行时间C++写法运行时间时间复杂度以及空间复杂度总结题目链接:240.......
  • 准确预测!最热门的自我测验,保证让你震撼不已!
    常用的自陈量表式测验MBTI性格类型测试MBTI性格理论始于著名心理学家荣格的心理类型的学说,后经美国的KatharineCookBriggs与IsabelBriggsMyers深入研究而发展成型。它已被翻译成十多种文字。近年来,全世界每年有200多万人次接受MBTI测试。据统计,世界前一百强公司中有89%......
  • 【力扣20】有效的括号
    20.有效的括号-力扣(LeetCode)括号序列压入栈中,遇到匹配的出栈,最后判断栈是否为空直接使用栈的数据结构stack。classSolution{public:boolisValid(strings){stack<char>stk;//初始化栈for(autoc:s){//入栈if(c=='......
  • 力扣题解2376
    大家好,欢迎来到无限大的频道。今日继续给大家带来力扣题解。题目描述(困难):统计特殊整数如果一个正整数每一个数位都是 互不相同 的,我们称它是 特殊整数 。给你一个 正 整数 n ,请你返回区间 [1,n] 之间特殊整数的数目。​解题思路:要计算区间([1,n])之间的......