文章目录
- 链表
- 21. 合并两个有序链表
- 栈
- 20. 有效的括号
- Java
- 栈
链表
- 链表的题目一般都不太难,画图,别怕麻烦
21. 合并两个有序链表
解法一:迭代
- 用一个指针
cur
跟踪当前节点,每次从list1
和list2
中选取小的节点,链接起来 - 建立一个头节点,可以简化最开始的判断,也可以简化对空链表的判断
- 最后会有一个链表先遍历完,而另一个链表直接链接在后面即可
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
// 建立一个头节点,可以简化代码
ListNode preHead = new ListNode(0);
ListNode cur = preHead; // 当前指针,用于更新链表
while(list1 != null && list2 != null){
if(list1.val < list2.val){
cur.next = list1;
list1 = list1.next;
}else{
cur.next = list2;
list2 = list2.next;
}
cur = cur.next;
}
cur.next = list1 == null ? list2 : list1; // 最后只有一个链表没走完,连接到后面即可
return preHead.next; // 头节点下一个节点即为所求
}
}
解法二:递归
- 可以把链接的过程看作:
list1
和list2
中较小的节点,与其余的所有节点合并的过程 - 考虑边界条件:
list1
或list2
为null
时,返回另一个
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
// 边界条件,一个为null
if(list1 == null) return list2;
if(list2 == null) return list1;
if(list1.val < list2.val){
list1.next = mergeTwoLists(list1.next, list2); // list1.next = 其余所有节点合并的结果
return list1;
}else{
list2.next = mergeTwoLists(list1, list2.next);
return list2;
}
}
}
栈
20. 有效的括号
思路
- 典型的栈的应用,合法的字符串中,右括号需要与左边与其最近的左括号匹配,这与栈LIFO的性质符合。我们可以利用一个栈储存左括号
- 遇到左括号,则将其入栈,等待右括号与其匹配。在代码实现上,可以入栈相应的右括号,方便后续匹配(这点之前没有学习到
- 遇到右括号,检查栈顶是否匹配。这里有两种情况不合法:一是栈空,二是栈顶不是对应括号。直接返回
false
;匹配,则出栈顶。 - 最后检查栈是否空,非空说明有左括号没有匹配,返回
false
;空说明均匹配,返回true
- ps:奇数长度的字符串,一定是非法的,可以提前排除
class Solution {
public boolean isValid(String s) {
int len = s.length();
if(len % 2 == 1) return false; // s长度为奇数,可以直接判错
Stack<Character> stack = new Stack<>();
for(int i=0;i<len;++i){
char ch = s.charAt(i);
// 这里,遇到左括号后,将对应正确的右括号入栈,方便后面判断
if(ch == '(') stack.push(')');
else if(ch == '[') stack.push(']');
else if(ch == '{') stack.push('}');
else{
if(stack.empty() || stack.peek() != ch) return false; // 右括号:栈空或者不匹配,则不合法,直接返回
stack.pop(); // 匹配,则出栈顶
}
}
return stack.empty(); // 最后检查栈空
}
}
Java
栈
Stack<Character> stk = new Stack<>()
:创建一个存储Character
类型值的栈bool empty()
:判断栈是否空peek()
:返回栈顶元素push()
:入栈pop()
:出栈