文章目录
- 链表
 - 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():出栈

















