leedcode刷题总结

类型一:字符串

1. 有效括号

给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。

有效字符串需满足:

左括号必须用相同类型的右括号闭合。

左括号必须以正确的顺序闭合。

每个右括号都有一个对应的相同类型的左括号。

public boolean isValid(String s) {

Map<Character,Character>map = new HashMap<Character,Character>();

map.put(')','(');

map.put(']','[');

map.put('}','{');

Stack<Character> stack = new Stack<Character>();

for(int i=0;i<s.length();i++){

char c = s.charAt(i);

if(!stack.isEmpty()&&map.containsKey(c)&&map.get(c)==stack.peek()){

stack.pop();

}else{

stack.push(c);

}

}

if(stack.isEmpty()){

return true;

}else{

return false;

}

}

解法一:

  1. 引入两块新的内存,map和stack

  2. stack用来存储字符的信息,通过出栈和入栈来进行操作

  3. 最后判断stack是否为空

解法二:通过一个栈来进行实现

实现原理:

"({[ ]})"

  1. 按照正确的匹配逻辑,如果是左括号,则对应的右括号入栈。

  2. 如果是右括号,则进行出栈操作

  3. 判断右括号是否对应

原因:

  1. 当我们遇到左括号 ( 时,我们 不是把 ( 压栈,而是压入它的配对 )

  2. 所以栈顶永远存的是"下一步期待出现的右括号"

public boolean isValid(String s) {

Stack<Character> stack = new Stack<>();

for(char c:s.toCharArray()){

if(c=='('){

stack.push(')');

}else if(c=='{'){

stack.push('}');

}else if(c=='['){

stack.push(']');

}else{

//栈为空,可能全部为右括号

if(stack.isEmpty() || stack.pop()!=c){

return false;

}

}

}

return stack.isEmpty();

}

2. 反转字符串:

编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。

不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。

public void reverseString(char[] s) {

int i=0;

int j = s.length-1;

while(i<j){

char temp = s[i];

s[i] = s[j];

s[j] = temp;

i++;

j--;

}

}

思想:通过双指针进行操作,没次交换以后

左指针进行++操作,右指针进行--操作。

为什么可以交换数组元素?

  1. 在 Java 中,数组是对象,数组名 s 是对数组对象的引用

  2. 数组元素是可变的(primitive 类型或对象引用都可以修改)

s[left] = s[right];

s[right] = temp;

拿到数组的某个位置,直接修改该位置的值

原数组 s 内的元素就被改变了

这是原地修改(in-place),不需要返回新的数组

3. 验证回文串

如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后,

短语正着读和反着读都一样。则可以认为该短语是一个 回文串 。

字母和数字都属于字母数字字符。给你一个字符串 s,

如果它是回文串 ,返回 true ;否则,返回 false 。

方法一:

思路:

1.先进行原始数据的处理,即先把数据处理成全部是字母和数字组成的小写字符串。

  1. 通过双指针进行回文数的判断

public boolean isPalindrome(String s) {

StringBuffer StringBuffer = new StringBuffer();

for(Character ch:s.toCharArray()){

if(Character.isLetterOrDigit(ch)){

StringBuffer.append(ch);

}

}

String str = StringBuffer.toString().toLowerCase();

int left = 0;

int right = str.length()-1;

while(left<right){

if(str.charAt(left)!=str.charAt(right)){

return false;

}

left ++;

right --;

}

return true;

}

Character:

isLetter():判断是否是字母。

isDigit: 判断是否是数字

isLetterOrDigit: 判断是否字母或者Digit

方法二:

思路:

  1. 直接在原始数据上面进行回文数的判断

  2. 优点不会创建新的对象,浪费资源

public boolean isPalindrome(String s) {

int left =0;

int right = s.length()-1;

while(left<right){

while(left<right&& !Character.isLetterOrDigit(s.charAt(left))){

left++;

}

while(left<right&& !Character.isLetterOrDigit(s.charAt(right))){

right--;

}

if(Character.toLowerCase(s.charAt(left))!=Character.toLowerCase(s.charAt(right))){

return false;

}

left++;

right--;

}

return true;

}

上面的两种方法,为啥第一种执行的时间短?

为什么方法一更快?

避免创建新对象

方法二会生成一个新的 StringBuffer,再生成一个 String → 额外分配内存 + 拷贝字符数组

方法一直接在原字符串上操作,没有内存分配开销

减少字符拷贝

方法二每个字母/数字字符都要 append + toLowerCase → 拷贝操作

方法一只比较,不生成任何数组

更少循环操作

方法一跳过非字母数字,只比较必要字符

方法二先遍历一次构建过滤字符串,再遍历一次判断 → 实际上多了一次遍历

4. 最后一个单词的长度

给你一个字符串 s,由若干单词组成,单词前后用一些空格字符隔开。

返回字符串中 最后一个 单词的长度。

单词 是指仅由字母组成、不包含任何空格字符的最大子字符串。

思路:从右向左进行遍历,获取第一个不为字母的空格。

public int lengthOfLastWord(String s) {

String str = s.trim();

int n=0;

for(int i=str.length()-1;i>=0;i--){

if(str.charAt(i) == ' '){

return n;

}

n++;

}

return n++;

}

public int lengthOfLastWord(String s) {

String str = s.trim();

String[] strs = s.split(" ");

if(strs.length==0){

return 0;

}

return strs[strs.length-1].length();

}

5. 找出字符串中第一个匹配项的下标

给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle

字符串的第一个匹配项的下标(下标从 0 开始)。

如果 needle 不是 haystack 的一部分,则返回 -1 。

public int strStr(String haystack, String needle) {

int first = haystack.indexOf(needle);

int last = haystack.lastIndexOf(needle);

if(first!=-1){

return first;

}

if(last!=-1){

return last;

}

return -1;

}

思路:

第一次出现的元素的位置:indexOf()

最后一次出现的元素的位置:lastIndexOf()

相关推荐
m0_748248652 小时前
C++正则表达式攻略:从基础到高级应用
java·c++·正则表达式
嫂子开门我是_我哥2 小时前
第十六节:异常处理:让程序在报错中稳定运行
开发语言·python
qq_12498707532 小时前
基于SpringBoot的闪电队篮球俱乐部管理系统的设计与开发(源码+论文+部署+安装)
java·数据库·spring boot·后端·spring·毕业设计·计算机毕业设计
a努力。2 小时前
中国邮政Java面试被问:MySQL的ICP(索引条件下推)优化原理
java·开发语言·数据仓库·面试·职场和发展·重构·maven
猿小羽2 小时前
Spring AI + MCP 实战:构建企业级 Agent 生态的基石
java·spring boot·llm·agent·spring ai·mcp·artificial intelligence
茶本无香2 小时前
设计模式之八: 适配器模式解释及应用
java·设计模式·适配器模式
青槿吖2 小时前
【趣味图解】线程同步与通讯:从抢奶茶看透synchronized、ReentrantLock和wait/notify
java·开发语言·jvm·算法
jiayong232 小时前
MQ基础概念面试题
java·kafka·rabbitmq·rocketmq
哪里不会点哪里.2 小时前
Spring Boot 自动装配原理深度解析
java·spring boot·后端