目录
20.有效的括号(括号匹配)
思路:
借助栈,左括号入栈,遇到右括号,就弹出栈顶的元素,看是否和这个右括号匹配,如果匹配,则继续下一个;如果不匹配,则输出false,最终为true的结果应该是栈里没有元素,全部匹配成功。
代码:
import java.util.Stack;
public class FortyfourIsvalid {
public boolean isValid(String s) {
//辅助栈
Stack<Character> c = new Stack<>();
for (int i = 0; i < s.length(); i++) {
//判断每一个字符
switch (s.charAt(i)) {
//如果是左括号,包括 ( [ { ,则入栈
case '(':
case '[':
case '{':
c.push(s.charAt(i));
break;
//如果是 ) ,则查看栈顶是否为空或者是 (
case ')':
//如果为空,且不是 ( ,说明没有匹配成功,返回false
if (c.isEmpty() || c.peek() != '(')
return false;
//如果匹配成功,则弹出 (
c.pop();
break;
case ']':
//如果为空,且不是 [ ,说明没有匹配成功,返回false
if (c.isEmpty() || c.peek() != '[')
return false;
//如果匹配成功,则弹出 [
c.pop();
break;
case '}':
//如果为空,且不是 { ,说明没有匹配成功,返回false
if (c.isEmpty() || c.peek() != '{')
return false;
//如果匹配成功,则弹出 {
c.pop();
break;
}
}
//如果最后栈为空,则说明全部匹配完毕,返回true,如果不为空,则说明没有全部匹配,返回false
return c.isEmpty()?true:false;
}
}
21.合并两个有序链表
思路:
采用递归地方法,两个链表头部值较小的一个节点与剩下元素的 merge
操作结果合并。
如果 l1 或者 l2 为空 ,则直接返回空链表。否则,首先判断 l1 和 l2 哪一个链表的头节点的值更小,然后递归地决定下一个添加到结果里的节点。如果两个链表有一个为空,递归结束。
(图源自官方题解)
代码:
class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
if (l1 == null) {
return l2;
} else if (l2 == null) {
return l1;
} else if (l1.val < l2.val) {
l1.next = mergeTwoLists(l1.next, l2);
return l1;
} else {
l2.next = mergeTwoLists(l1, l2.next);
return l2;
}
}
}
22.括号生成
思路:
回溯与递归,由题意知,一共有n个左括号和n个右括号,每当我们使用一个左括号之后,就剩下n−1个左括号和n个右括号,并拼在使用的左括号之后就行了,因此后者就是一个子问题,可以使用递归:
- 终止条件: 左右括号都使用了n个,将正确的括号序列加入数组。
- 返回值: 每一级向上一级返回后续组装后的字符串,即子问题中搭配出来的括号序列。
- 本级任务: 每一级就是保证左括号还有剩余的情况下,使用一次左括号进入子问题,或者右括号还有剩余且右括号使用次数少于左括号的情况下使用一次右括号进入子问题。
这个递归是树型递归,需要我们进行回溯,即当我们得到一个正确的括号序列时,应当回溯到父问题,进行另外分支的递归。下面展示牛客官方的图片,动图请移步:
代码:
public class Solution {
public ArrayList<String> generateParenthesis (int n) {
// write code here
ArrayList<String> res = new ArrayList<>();
recursion(0,0,"",res,n);
return res;
}
public void recursion(int left, int right, String temp,ArrayList<String> res, int n){
//左右括号都用完了,就加入结果
if (left == n && right == n){
res.add(temp);
return;
}
//使用以此小括号
if (left< n){
recursion(left+1,right,temp+"(",res,n);
}
//使用右括号的数量少于左括号
if(right < n && left > right){
recursion(left, right + 1,temp + ")", res, n);
}
}
}