【字符串 简单】LeetCode 14. 最长公共前缀 Java

news2024/11/28 11:57:01

在这里插入图片描述
我的思路:

  1. 给字符串数组按照字符串的长度从长到短排序,因为最长公共前缀最长的话,也只能是字符串数组中最短的那一个字符串
  2. 设置一个index变量,表示当前正在检查字符数组中所有字符串的index位置
  3. 循环遍历字符串数组n遍,n也就是最长公共前缀的长度
import java.util.Arrays;
import java.util.Comparator;

class Solution {
    public String longestCommonPrefix(String[] strs) {
        int index = 0;
        Arrays.sort(strs, Comparator.comparingInt(String::length));

        while (index < strs[0].length()) {
            boolean isSame = true;
            char c = strs[0].charAt(index);
            for (int i = 1; i < strs.length; i++) {
                if (c != strs[i].charAt(index)) {
                    isSame = false;
                    break;
                }
            }
            if (!isSame) {
                return strs[0].substring(0, index);
            }
            index++;
        }
        return strs[0];
    }
}

在这里插入图片描述

其他思路,方法一,横向扫描

用LCP(S1,S2,…,Sn)表示字符串S1,S2,…Sn的最长公共前缀。

那么,LCP(S1,S2,…,Sn) = LCP(LCP(LCP(S1,S2),S3),…Sn)

基于该结论,可以得到一种查找字符串数组中的最长公共前缀的简单方法。依次遍历字符串数组中的每一个字符串,对于每个遍历到字符串,更新最长公共前缀,当遍历完所有的字符串以后,即可得到字符串数组中的最长公共前缀。

如果在尚未遍历完所有的字符串时,最长公共前缀已经是空串,则最长公共前缀一定是空串,因此不需要继续遍历剩下的字符串,直接返回空串即可。

class Solution {
    public String longestCommonPrefix(String[] strs) {
        String prefix = strs[0];
        int count = strs.length;
        for (int i = 1; i < count; i++) {
            prefix = longestCommonPrefix(prefix, strs[i]);
            if (prefix.length() == 0) {
                break;
            }
        }
        return prefix;
    }

    public String longestCommonPrefix(String str1, String str2) {
        int length = Math.min(str1.length(), str2.length());
        int index = 0;
        while (index < length && str1.charAt(index) == str2.charAt(index)) {
            index++;
        }
        return str1.substring(0, index);
    }
}

复杂度分析:

  • 时间复杂度:O(mn),其中,m是字符串数组中的字符串的平均长度,n是字符串的数量。最坏情况下,字符串数组中的每个字符串的每个字符都会被比较一次。
  • 空间复杂度:O(1)。使用的额外空间复杂度为常数。

在这里插入图片描述
其他思路,方法二,纵向扫描

纵向扫描时,从前往后遍历所有字符串的每一列,比较相同列上的字符是否相同,如果相同则继续对下一列进行比较,如果不相同,则当前列不属于公共前缀,当前列之前的部分为最长公共前缀。

class Solution {
    public String longestCommonPrefix(String[] strs) {

        //字符串数组中第一个字符串的长度
        int length = strs[0].length();

        //字符串数组的长度
        int count = strs.length;

        //最长公共前缀的长度一定不会超过字符串数组中第一个字符串的长度
        for (int i = 0; i < length; i++) {

            //开始纵向比较
            char c = strs[0].charAt(i);
            for (int j = 1; j < count; j++) {
                if (i == strs[j].length() || c != strs[j].charAt(i)) {
                    return strs[0].substring(0, i);
                }
            }
        }
        return strs[0];
    }
}

在这里插入图片描述
方法三,分治

注意,LCP的计算满足结合律,有以下结论:

LCP(S1…Sn) = LCP(LCP(S1…Sk),LCP(Sk+1…Sn))

class Solution {
    public String longestCommonPrefix(String[] strs) {
        int strsLength = strs.length;
        return longestCommonPrefix(strs, 0, strsLength - 1);
    }


    public String longestCommonPrefix(String[] strs, int start, int end) {
        if (start == end) {
            return strs[start];
        }
        if (end - start == 1) {
            return commonPrefix(strs[start], strs[end]);
        }
        int mid = (start + end) / 2;
        String lcpLeft = longestCommonPrefix(strs, start, mid);
        String lcpRight = longestCommonPrefix(strs, mid + 1, end);
        return commonPrefix(lcpLeft, lcpRight);
    }

    public String commonPrefix(String lcpLeft, String lcpRight) {
        int minLength = Math.min(lcpLeft.length(), lcpRight.length());
        for (int i = 0; i < minLength; i++) {
            if (lcpLeft.charAt(i) != lcpRight.charAt(i)) {
                return lcpLeft.substring(0, i);
            }
        }
        return lcpLeft.substring(0, minLength);
    }
}

复杂度分析:

  • 时间复杂度:O(mn),其中m是字符串数组中的字符串的平均长度,n是字符串的数量。时间复杂度的递推式是 T ( n ) = 2 ⋅ T ( n 2 ) + O ( m ) T(n)=2 \cdot T(\frac{n}{2})+O(m) T(n)=2T(2n)+O(m),通过计算可得 T ( n ) = O ( m n ) T(n)=O(mn) T(n)=O(mn)
  • 空间复杂度:KaTeX parse error: Undefined control sequence: \logn at position 4: O(m\̲l̲o̲g̲n̲),其中m是字符串数组中的字符串的平均长度,n是字符串的数量。空间复杂度主要取决于递归调用的层数,层数最大为KaTeX parse error: Undefined control sequence: \logn at position 1: \̲l̲o̲g̲n̲,每层需要m的空间存储返回结果。

在这里插入图片描述
方法四,二分查找

显然,最长公共前缀的长度不会超过字符串数组中的最短字符串的长度。用minLength表示字符串数组中的最短字符串的长度,则可以在[0,minLength]的范围内通过二分查找得到最长公共前缀的长度,每次取查找范围的中间值mid,判断每个字符串的长度为mid的前缀是否相同,如果相同则最长公共前缀的长度一定大于或等于mid,如果不相同则最长公共前缀的长度一定小于mid,通过上述方式将查找范围缩小一半,直到得到最长公共前缀的长度。

class Solution {
    public String longestCommonPrefix(String[] strs) {
        int minLength = Integer.MAX_VALUE;
        for (String str : strs) {
            minLength = Math.min(minLength, str.length());
        }
        int left = 0;
        int right = minLength;
        //[left,right)

        while (left < right) {
            //在偶数长度的区间时,mid往右边靠
            int mid = (left + right + 1) / 2 ;
            //int mid = (left + right + 1) / 2;
            if (isCommonPrefix(strs, mid)) {
                //可能mid就是最长公共前缀的长度
                left = mid;
            } else {
                right = mid - 1;
            }
        }
        //最后一次left的值,肯定是合理的
        return strs[0].substring(0, left);
    }

    public boolean isCommonPrefix(String[] strs, int length) {
        //拿到数组中的第一个字符串中的长度为length的子串
        String str0 = strs[0].substring(0, length);

        //获取整个字符串数组的长度
        int count = strs.length;

        for (int i = 1; i < count; i++) {
            String str = strs[i];
            for (int j = 0; j < length; j++) {
                if (str0.charAt(j) != str.charAt(j)) {
                    return false;
                }
            }
        }
        return true;
    }
}

复杂度分析:

  • 时间复杂度:O(mnlogm),其中m是字符串数组中的字符串的最小长度,n是字符串的数量。二分查找的迭代执行次数是O(logm),每次迭代最多需要比较mn个字符,因此总时间复杂度是O(mnlogm)
  • 空间复杂度:O(1),使用的额外空间复杂度是常数

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/741912.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java设计模式之结构型-桥接模式(UML类图+案例分析)

目录 一、基础概念 二、UML类图 三、角色分析 四、案例分析 1、支付方式 2、支付渠道 五、总结 一、基础概念 桥接模式&#xff08;Bridge Pattern&#xff09;是一种结构型设计模式&#xff0c;其主要目的是“将抽象部分与实现部分分离&#xff0c;使它们都可以独立地…

微信小程序扫码邀请,小程序码生成带参数

代码一&#xff1a; public String generateQRCode(String appId, String appSecret, String pagePath) throws IOException {String accessToken getAccessToken(appId, appSecret);String apiUrl "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token&qu…

springboot家乡特色推荐系统

本次设计任务是要设计一个家乡特色推荐系统&#xff0c;通过这个系统能够满足家乡特色文章的管理功能。系统的主要功能包括首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;文章分类管理&#xff0c;文章分享管理&#xff0c;系统管理等。 管理员可以根据系统给定的账…

前端工程化与webpack

一、目标 能够说出什么是前端工程化能够说出webpack的作用能够掌握webpack的基本使用了解常用plugin的基本使用了解常用loader的基本使用能够说出Source Map的作用 二、目录 前端工程化webpack的基本使用webpack中的插件webpack中的loader打包发布Source Map 1.前端工程化 …

2023年Q2京东冰箱行业品牌销售排行榜(京东销售数据分析)

近年我国的冰箱零售呈波动变化的趋势&#xff0c;由于冰箱市场趋于饱和&#xff0c;因此消费者对冰箱的需求逐渐变为替换需求&#xff0c;这也进一步推动了产品的更新迭代。接下来结合具体数据&#xff0c;我们来分析一下2023年Q2冰箱行业的销售详情。 根据鲸参谋电商数据分析平…

MySQL环境配置

MySQL在centos7环境安装 一.卸载不要的环境二.获取mysql官方yum源三.安装mysql服务四.mysql登陆五.设置配置文件my.cnf六.设置开机启动【可以不设】七.常见问题 安装与卸载中&#xff0c;⽤⼾全部切换成为root&#xff0c;⼀旦安装&#xff0c;普通⽤⼾也能使⽤。 一.卸载不要…

Python编程——字符串的三种定义方式讲解

作者&#xff1a;Insist-- 个人主页&#xff1a;insist--个人主页 本文专栏&#xff1a;python专栏 专栏介绍&#xff1a;本专栏为免费专栏&#xff0c;并且会持续更新python基础知识&#xff0c;欢迎各位订阅关注。 前言 上篇文章讲了python字符串的一些知识&#xff0c;现在…

[ICASSP 2019] 差分隐私压缩 K 均值

Differentially Private Compressive K-means Differentially Private Compressive K-means | IEEE Conference Publication | IEEE Xplore 摘要&#xff1a; 这项工作解决了从大量数据中学习并保证隐私的问题。概述的学习框架建议通过将大规模数据集压缩为广义随机矩的单个向…

Arduino为GD32芯片编程

GD32F103用Arduino编程 板子线路图Ardunino编程程序编制编译下载 板子线路图 这个STM32F103C8T6用国产的GD32来代替。 Ardunino编程 使用Arduino编程&#xff0c;在板子管理器中安装&#xff1a; 安装需要一些时间&#xff0c;在这里可以看到&#xff0c;STM32F1xx支持GD32F…

Flink-intervalJoin源码和并行度问题

1.源码 底层用的是connect 把两个流的数据先保存到状态中 先判断有没有迟到&#xff0c;迟到就放到侧输出流 再根据范围找数据 然后根据上界删除数据 package com.atguigu.gmall.realtime.test;import org.apache.flink.api.common.eventtime.SerializableTimestampAssigne…

【Java基础教程】(十一)面向对象篇 · 第五讲:透彻讲解Java中的static关键字及代码块——静态属性、静态方法和普通代码块、构造块、静态块的使用~

Java基础教程之面向对象 第五讲 本节学习目标1️⃣ static 关键字1.1 static定义静态属性1.2 static定义静态方法1.3 主方法1.4 实际应用功能一&#xff1a;实现类实例化对象个数的统计功能二&#xff1a; 实现属性的自动设置 2️⃣ 代码块2.1 普通代码块2.2 构造块2.3 静态块…

gulimall-首页渲染-nginx域名搭建

首页渲染与nginx域名搭建 前言一、首页1.1 整合 thymeleaf1.2 整合 dev-tools1.3 渲染分类数据 二、Nginx 域名搭建2.1 搭建域名访问环境2.2 nginx 配置文件2.3 总结 前言 本文继续记录B站谷粒商城项目视频 P136-140 的内容&#xff0c;做到知识点的梳理和总结的作用。 一、首…

组合取球-2022年全国青少年信息素养大赛Python国赛第6题

[导读]&#xff1a;超平老师计划推出《全国青少年信息素养大赛Python编程真题解析》50讲&#xff0c;这是超平老师解读Python编程挑战赛真题系列的第8讲。 全国青少年信息素养大赛&#xff08;原全国青少年电子信息智能创新大赛&#xff09;是“世界机器人大会青少年机器人设计…

教你如何自定义 Github 首页

一、创建自定义首页仓库 若要自定义首页&#xff0c;首先需要创建一个与你 Github ID 同名的仓库 创建完成后就可以开始为你的首页添加一些有趣的内容了&#xff0c;代码格式可以是 markdown 语法&#xff0c;也可以是 HTML 语法&#xff0c;但 HTML 的扩展性更强一点&#xf…

大唐京兆韦氏,两个老来发奋的诗人

在唐朝&#xff0c;诗人文学政治家如过江之鲫&#xff0c;有两个人物是绝对不可忽略的&#xff0c;那就是韦应物和韦庄。其中韦应物是韦庄的曾祖父。 京兆韦氏是整个唐朝时期最重要的士族家族之一&#xff0c;代有人才出&#xff0c;衣冠鼎盛&#xff0c;为关中望姓之首。韦氏…

I/O多复用函数(select、poll、epoll)

目录 一、select函数二、poll函数 select函数 int select(int nfds, fd_set *readfds, fd_set *writefds,fd_set *exceptfds, struct timeval *timeout);poll函数 int poll(struct pollfd *fds, nfds_t nfds, int timeout);epoll API epoll_create epoll_wait epoll_ctl一、sel…

Spring Boot 系列3 -- 日志文件

目录 1. 日志有什么用? 2. 日志的使用 2.1 得到日志对象 2.2 使用日志对象打印日志 3. 日志级别 3.1 日志级别的用途 3.2 日志级别的分类和使用 3.3 日志的打印规则 3.4 日志级别的设置 4. 日志持久化 5. 更简单的日志输出--lombok 6. 拓展1 lombok的原理 7. 拓…

SSM整合-1

SSM整合 创建工程SSM整合 2.1 Spring: SpringConfig 2.2 SpringMvc: ServletConfig、SpringMvcConfig 3.3 Mybatis JdbcConfig、MybatisConfig、jdbc.properties 3.功能模块 表与实体类 dao(接口自动代理) service(接口实现类) 业务层接口测试&#xff08;整合Junit&#xff…

在vite创建的vue3项目中使用Cesium加载立体地形信息并调整初始化角度

在vite创建的vue3项目中使用Cesium加载立体地形信息并调整初始化角度 使用vite创建vue3项目 npm create vitelatestcd到创建的项目文件夹中 npm install安装Cesium npm i cesium vite-plugin-cesium vite -D配置 &#xff08;1&#xff09;在项目的vite.config.js文件中添加&am…

新手学习编程有什么注意事项?

为什么要学习如何编码&#xff1f; 世界正在成为一个地球村。编码是它发生的一个重要原因。 你应该学习如何编码的原因有很多&#xff0c;我将在这里触及其中的一些。 首先&#xff0c;学习编码可以大大提高你的分析和解决问题的能力。 您的收入潜力增加&#xff1a;有高级开…