leetcode第5~6题

简介: 我们可以看到,图形其实是有周期的,0,1,2 ... 7 总过 8 个,然后就又开始重复相同的路径。周期的计算就是 cycleLen = 2 × numRows - 2 = 2 × 5 - 2 = 8 个。我们发现第 0 行和最后一行一个周期内有一个字符,所以第一个字符下标是 0 ,第二个字符下标是 0 + cycleLen = 8,第三个字符下标是 8 + cycleLen = 16 。其他行都是两个字符。第 1 个字符和第 0 行的规律是一样的。第 2 个字符其实就是下一个周期的第 0 行的下标减去当前行。什么意思呢?我们求一下第 1 行第 1 个周期内的第 2 个字符

top5

给定一个字符串,输出最长的回文子串。回文串指的是正的读和反的读是一样的字符串,例如 "aba","ccbbcc"。

解法一 暴力破解

暴力求解,列举所有的子串,判断是否为回文串,保存最长的回文串。

publicbooleanisPalindromic(Strings) {
intlen=s.length();
for (inti=0; i<len/2; i++) {
if (s.charAt(i) !=s.charAt(len-i-1)) {
returnfalse;
            }
        }
returntrue;
    }
// 暴力解法publicStringlongestPalindrome(Strings) {
Stringans="";
intmax=0;
intlen=s.length();
for (inti=0; i<len; i++)
for (intj=i+1; j<=len; j++) {
Stringtest=s.substring(i, j);
if (isPalindromic(test) &&test.length() >max) {
ans=s.substring(i, j);
max=Math.max(max, ans.length());
            }
        }
returnans;
}

时间复杂度:两层 for 循环 O(n²),for 循环里边判断是否为回文,O(n),所以时间复杂度为 O(n³)。

空间复杂度:O(1),常数个变量。


解法二 最长公共子串

根据回文串的定义,正着和反着读一样,那我们是不是把原来的字符串倒置了,然后找最长的公共子串就可以了。例如,S = " caba",S' = " abac",最长公共子串是 "aba",所以原字符串的最长回文串就是 "aba"。

关于求最长公共子串(不是公共子序列),有很多方法,这里用动态规划的方法,可以先阅读下边的链接。

https://blog.csdn.net/u010397369/article/details/38979077

https://www.kancloud.cn/digest/pieces-algorithm/163624

整体思想就是,申请一个二维的数组初始化为 0,然后判断对应的字符是否相等,相等的话

arr [ i ][ j ] = arr [ i - 1 ][ j - 1] + 1 。

当 i = 0 或者 j = 0 的时候单独分析,字符相等的话 arr [ i ][ j ] 就赋为 1 。

arr [ i ][ j ] 保存的就是公共子串的长度。


publicStringlongestPalindrome(Strings) {
if (s.equals(""))
return"";
Stringorigin=s;
Stringreverse=newStringBuffer(s).reverse().toString(); //字符串倒置intlength=s.length();
int[][] arr=newint[length][length];
intmaxLen=0;
intmaxEnd=0;
for (inti=0; i<length; i++)
for (intj=0; j<length; j++) {
if (origin.charAt(i) ==reverse.charAt(j)) {
if (i==0||j==0) {
arr[i][j] =1;
                } else {
arr[i][j] =arr[i-1][j-1] +1;
                }
            }
if (arr[i][j] >maxLen) { 
maxLen=arr[i][j];
maxEnd=i; //以 i 位置结尾的字符            }
        }
    }
returns.substring(maxEnd-maxLen+1, maxEnd+1);
}

再看一个例子,S = "abc435cba",S’ = "abc534cba" ,最长公共子串是 "abc" 和 "cba" ,但很明显这两个字符串都不是回文串。

所以我们求出最长公共子串后,并不一定是回文串,我们还需要判断该字符串倒置前的下标和当前的字符串下标是不是匹配。

比如 S = " caba ",S' = " abac " ,S’ 中 aba 的下标是 0 1 2 ,倒置前是 3 2 1,和 S 中 aba 的下标符合,所以 aba 就是我们需要找的。当然我们不需要每个字符都判断,我们只需要判断末尾字符就可以。

image.png



首先 i ,j 始终指向子串的末尾字符。所以 j 指向的红色的 a 倒置前的下标是 beforeRev = length - 1 - j = 4 - 1 - 2 = 1,对应的是字符串首位的下标,我们还需要加上字符串的长度才是末尾字符的下标,也就是 beforeRev + arr[ i ] [ j ] - 1 = 1 + 3 - 1 = 3,因为 arr[ i ] [ j ] 保存的就是当前子串的长度,也就是图中的数字 3 。此时再和它与 i 比较,如果相等,则说明它是我们要找的回文串。

之前的 S = "abc435cba",S' = "abc534cba" ,可以看一下图示,为什么不符合。

image.png


当前 j 指向的 c ,倒置前的下标是 beforeRev = length - 1 - j = 9 - 1 - 2 = 6,对应的末尾下标是 beforeRev + arr[ i ] [ j ] - 1 = 6 + 3 - 1 = 8 ,而此时 i = 2 ,所以当前的子串不是回文串。

代码的话,在上边的基础上,保存 maxLen 前判断一下下标匹不匹配就可以了。


publicStringlongestPalindrome(Strings) {
if (s.equals(""))
return"";
Stringorigin=s;
Stringreverse=newStringBuffer(s).reverse().toString();
intlength=s.length();
int[][] arr=newint[length][length];
intmaxLen=0;
intmaxEnd=0;
for (inti=0; i<length; i++)
for (intj=0; j<length; j++) {
if (origin.charAt(i) ==reverse.charAt(j)) {
if (i==0||j==0) {
arr[i][j] =1;
                } else {
arr[i][j] =arr[i-1][j-1] +1;
                }
            }
/**********修改的地方*******************/if (arr[i][j] >maxLen) {
intbeforeRev=length-1-j;
if (beforeRev+arr[i][j] -1==i) { //判断下标是否对应maxLen=arr[i][j];
maxEnd=i;
                }
/*************************************/            }
        }
returns.substring(maxEnd-maxLen+1, maxEnd+1);
}

时间复杂度:两层循环,O(n²)。

空间复杂度:一个二维数组,O(n²)。


top6


就是给定一个字符串,然后按写竖着的 「z」的方式排列字符,就是下边的样子。

然后按行的方式输出每个字符,第 0 行,第 1 行,第 2 行 ....

解法一

按照写 Z 的过程,遍历每个字符,然后将字符存到对应的行中。用 goingDown 保存当前的遍历方向,如果遍历到两端,就改变方向。

publicStringconvert(Strings, intnumRows) {
if (numRows==1) returns;
List<StringBuilder>rows=newArrayList<>();
for (inti=0; i<Math.min(numRows, s.length()); i++)
rows.add(newStringBuilder());
intcurRow=0;
booleangoingDown=false;
for (charc : s.toCharArray()) {
rows.get(curRow).append(c);
if (curRow==0||curRow==numRows-1) goingDown=!goingDown; //遍历到两端,改变方向curRow+=goingDown?1 : -1;
        }
StringBuilderret=newStringBuilder();
for (StringBuilderrow : rows) ret.append(row);
returnret.toString();
    }

时间复杂度:O(n),n 是字符串的长度。

空间复杂度:O(n),保存每个字符需要的空间。

解法二

找出按 Z 形排列后字符的规律,然后直接保存起来。

我们可以看到,图形其实是有周期的,0,1,2 ... 7 总过 8 个,然后就又开始重复相同的路径。周期的计算就是 cycleLen = 2 × numRows - 2 = 2 × 5 - 2 = 8 个。

我们发现第 0 行和最后一行一个周期内有一个字符,所以第一个字符下标是 0 ,第二个字符下标是 0 + cycleLen = 8,第三个字符下标是 8 + cycleLen = 16 。

其他行都是两个字符。

第 1 个字符和第 0 行的规律是一样的。

第 2 个字符其实就是下一个周期的第 0 行的下标减去当前行。什么意思呢?

我们求一下第 1 行第 1 个周期内的第 2 个字符,下一个周期的第 0 行的下标是 8 ,减去当前行 1 ,就是 7 了。

我们求一下第 1 行第 2 个而周期内的第 2 个字符,下一个周期的第 0 行的下标是 16 ,减去当前行 1 ,就是 15 了。

我们求一下第 2 行第 1 个周期内的第 2 个字符,下一个周期的第 0 行的下标是 8 ,减去当前行 2 ,就是 6 了。

当然期间一定要保证下标小于 n ,防止越界。

可以写代码了。


publicStringconvert(Strings, intnumRows) {
if (numRows==1)
returns;
StringBuilderret=newStringBuilder();
intn=s.length();
intcycleLen=2*numRows-2;
for (inti=0; i<numRows; i++) {
for (intj=0; j+i<n; j+=cycleLen) { //每次加一个周期ret.append(s.charAt(j+i));
if (i!=0&&i!=numRows-1&&j+cycleLen-i<n) //除去第 0 行和最后一行ret.append(s.charAt(j+cycleLen-i));
        }
    }
returnret.toString();
}


时间复杂度:O(n),虽然是两层循环,但第二次循环每次加的是 cycleLen ,无非是把每个字符遍历了 1 次,所以两层循环内执行的次数肯定是字符串的长度。

空间复杂度:O(n),保存字符串。

相关文章
|
14天前
|
存储 弹性计算 人工智能
【2025云栖精华内容】 打造持续领先,全球覆盖的澎湃算力底座——通用计算产品发布与行业实践专场回顾
2025年9月24日,阿里云弹性计算团队多位产品、技术专家及服务器团队技术专家共同在【2025云栖大会】现场带来了《通用计算产品发布与行业实践》的专场论坛,本论坛聚焦弹性计算多款通用算力产品发布。同时,ECS云服务器安全能力、资源售卖模式、计算AI助手等用户体验关键环节也宣布升级,让用云更简单、更智能。海尔三翼鸟云服务负责人刘建锋先生作为特邀嘉宾,莅临现场分享了关于阿里云ECS g9i推动AIoT平台的场景落地实践。
【2025云栖精华内容】 打造持续领先,全球覆盖的澎湃算力底座——通用计算产品发布与行业实践专场回顾
|
6天前
|
云安全 人工智能 安全
Dify平台集成阿里云AI安全护栏,构建AI Runtime安全防线
阿里云 AI 安全护栏加入Dify平台,打造可信赖的 AI
|
9天前
|
人工智能 运维 Java
Spring AI Alibaba Admin 开源!以数据为中心的 Agent 开发平台
Spring AI Alibaba Admin 正式发布!一站式实现 Prompt 管理、动态热更新、评测集构建、自动化评估与全链路可观测,助力企业高效构建可信赖的 AI Agent 应用。开源共建,现已上线!
838 25
|
8天前
|
机器学习/深度学习 人工智能 搜索推荐
万字长文深度解析最新Deep Research技术:前沿架构、核心技术与未来展望
近期发生了什么自 2025 年 2 月 OpenAI 正式发布Deep Research以来,深度研究/深度搜索(Deep Research / Deep Search)正在成为信息检索与知识工作的全新范式:系统以多步推理驱动大规模联网检索、跨源证据。
576 46
|
2天前
|
监控 BI 数据库
打工人救星!来看看这两家企业如何用Quick BI让业务更高效
Quick BI专业版监控告警助力企业高效运作,通过灵活配置规则与多渠道推送,让数据异常早发现、快响应,推动业务敏捷决策与持续增长。
打工人救星!来看看这两家企业如何用Quick BI让业务更高效
|
8天前
|
人工智能 Java Nacos
基于 Spring AI Alibaba + Nacos 的分布式 Multi-Agent 构建指南
本文将针对 Spring AI Alibaba + Nacos 的分布式多智能体构建方案展开介绍,同时结合 Demo 说明快速开发方法与实际效果。
562 41