20, 21, 22, 23 questions of LeetCode Top100

20. Valid parentheses

① Title description
  • Given a string that only includes'(',')','{','}','[',']', judge whether the string is valid.
  • A valid string must satisfy: the
    left parenthesis must be closed with the same type of right parenthesis.
    The opening parenthesis must be closed in the correct order.
    Note that an empty string can be considered a valid string.
  • Example 1:

Input: "()"
Output: true

  • Example 2:

Input: "()[]{}"
Output: true

  • Example 3:

Input: "(]"
Output: false

  • Example 4:

Input: "([)]"
Output: false

  • Example 5:

Input: "{[]}"
Output: true

② Use stack (Stack)
  • Bracket pairing problem, the typical method-use stack. As stackit is emptywhen the bracket is pressed into stack; and when the current top of the stack to be scanned paired parentheses, brackets pop the stack; if not met directly pressed stack, for example ({[.
  • Time complexity: O(n)as we traversed only once to a given character string and on the stack O(1)push and pop operations.
  • Space complexity: O(n)When we push all the open parentheses on the stack and in the worst case, we end up pushing all the parentheses on the stack. For example ((((((((((.
  • code show as below:
public boolean isValid(String s) {
    
    
    int len = s.length();
    if (len == 0) {
    
    
        return true;
    }
    if (len % 2 != 0) {
    
    
        return false;
    }
    Stack<Character> stack = new Stack<>();
    for (int i = 0; i < len; i++) {
    
    
        if (stack.isEmpty()) {
    
    
            stack.push(s.charAt(i));
        } else {
    
    
            if (stack.peek() == '(' && s.charAt(i) == ')') {
    
    
                stack.pop();
            } else if (stack.peek() == '[' && s.charAt(i) == ']') {
    
    
                stack.pop();
            } else if (stack.peek() == '{' && s.charAt(i) == '}') {
    
    
                stack.pop();
            } else {
    
    
                stack.push(s.charAt(i));
            }
        }
    }
    if (stack.isEmpty()) {
    
    
        return true;
    }
    return false;
}

21. Merge two ordered linked lists

① Title description
  • Combine two ordered linked lists into a new ordered linked list and return. The new linked list is composed by splicing all the nodes of the given two linked lists.
  • Example:

Input: 1->2->4, 1->3->4
Output: 1->1->2->3->4->4

② With the help of the new linked list head
  • By comparing the val of the l1sum l2, it is decided whether to l1add a new linked list or a l2new linked list, and update the l1or l2pointer.
  • Pay attention to special cases:
    l1Or l2null, directly return to another linked list;
    ② After completing the merge, there is always a linked list not at the end, just add it to the new linked list.
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
    
    
    //可以提前判断,也可以不用判断
    if (l1 == null) {
    
    
        return l2;
    }
    if (l2 == null) {
    
    
        return l1;
    }
    ListNode result = new ListNode(0);
    ListNode cur = result;
    while (l1 != null && l2 != null) {
    
    
        if (l1.val < l2.val) {
    
    
            cur.next = l1;
            l1 = l1.next;
        } else {
    
    
            cur.next = l2;
            l2 = l2.next;
        }
        cur = cur.next;
    }
    if (l1 != null) {
    
    
        cur.next = l1;
    } else {
    
    
        cur.next = l2;
    }
    return result.next;
}

22. Bracket generation

① Title description
  • Given that n represents the logarithm of generating parentheses, please write a function that can generate all possible and effective parentheses combinations.
  • For example, given n = 3, the generated result is:

[
      "((()))",
      "(()())",
      "(())()",
      "()(())",
      "()()()"
]

② Backtracking method
public List<String> generateParenthesis(int n) {
    
    
    List<String> result = new ArrayList<>();
    if (n == 0) {
    
    
        return result;
    }
    helper(result, "", 0, 0, n);
    return result;

}

public void helper(List<String> result, String s, int open, int close, int n) {
    
    
    if (s.length() == n * 2) {
    
    
        result.add(s);
        return;
    }
    if (open < n) {
    
    
        helper(result, s + "(", open + 1, close, n);
    }
    if (open > close) {
    
    
        helper(result, s + ")", open, close + 1, n);
    }

}
③ Violence law
public List<String> generateParenthesis(int n) {
    
    
    List<String> result = new ArrayList<>();
    if (n == 0) {
    
    
        return result;
    }
    helper(result, "", n);
    return result;

}

public void helper(List<String> result, String s, int n) {
    
    
    if (s.length() == n * 2) {
    
    
        if (isTrue(s)) {
    
    
            result.add(s);
        }
        return;
    }
    helper(result, s + "(", n);
    helper(result, s + ")", n);

}

public boolean isTrue(String s) {
    
    
    int count = 0;
    for (int i = 0; i < s.length(); i++) {
    
    
        if (s.charAt(i) == '(') {
    
    
            count++;
        } else {
    
    
            count--;
        }
        if (count < 0) {
    
    
            return false;
        }
    }
    return count == 0;
}

23. Merge K sorted linked lists

① Title description
  • Combine k sorted linked lists and return the merged sorted linked list. Please analyze and describe the complexity of the algorithm.
  • Example:

Input: [ 1->4->5, 1->3->4, 2->6]
Output:1->1->2->3->4->4->5->6

② own stupid way
  • First obtain the node values ​​of all sorted linked lists, and store them in the new linked list after re-sorting.
  • Use Listand skillfully to Collections.sort()realize quick reordering.
  • code show as below:
public ListNode mergeKLists(ListNode[] lists) {
    
    
    ListNode result = new ListNode(0);
    ListNode cur = reuslt;
    if (lists.length == 1) {
    
    
        return lists[0];
    }
    List<Integer> arr = new ArrayList<>();
    for (int i = 0; i < lists.length; i++) {
    
    
        ListNode p = lists[i];
        while (p != null) {
    
    
            arr.add(p.val);
            p = p.next;
        }
    }
    Collections.sort(arr);
    for (int i = 0; i < arr.size(); i++) {
    
    
        ListNode node = new ListNode(arr.get(i));
        cur.next = node;
        cur = cur.next;
    }
    cur.next = null;
    return result.next;
}
③ Comparison column by column (the effect seems to be much worse than my own stupid method)
  • Align all the linked lists, look up the minimum value of the current column one by one, until all the linked lists are null.
  • The schematic diagram is as follows:
    Insert picture description here
  • code show as below:
public ListNode mergeKLists(ListNode[] lists) {
    
    
    ListNode result = new ListNode(0);
    ListNode cur = reuslt;
    if (lists.length == 1) {
    
    
        return lists[0];
    }

    while (true) {
    
    
        int min = Integer.MAX_VALUE;
        int min_index = 0;
        boolean flag = true;
        for (int i = 0; i < lists.length; i++) {
    
    
            if (lists[i] != null) {
    
    
                if (lists[i].val < min) {
    
    
                    min = lists[i].val;
                    min_index = i;
                }
                flag = false;
            }
        }
        if (flag) {
    
    
            break;
        }
        cur.next = lists[min_index];
        cur = cur.next;
        lists[min_index] = lists[min_index].next;
    }
    cur.next = null;
    return result.next;
}
④ Use priority queue (master the definition of priority queue)
  • Realize the targeted ListNodepriority queue by customizing the comparator . The overall idea is the 一列一列的比较same, except that the comparison process is handed over to the priority queue to complete it.
Queue<ListNode> q = new PriorityQueue<ListNode>(cmp);
  • Pay attention to the particularity of the linked list. It seems that one node is stored in the queue, but in fact it stores the entire linked list.
  • When initializing the priority queue, do not forget to judge lists[i]whether it is null!
Comparator<ListNode> cmp = new Comparator<ListNode>() {
    
     // 自定义比较器
    @Override
    public int compare(ListNode o1, ListNode o2) {
    
    
        return o1.val - o2.val;
    }
};

public ListNode mergeKLists(ListNode[] lists) {
    
    
    ListNode result = new ListNode(0);
    ListNode cur = result;
    if (lists.length == 1) {
    
    
        return lists[0];
    }
    //建立队列,每个位置存储一个链表
    Queue<ListNode> q = new PriorityQueue<ListNode>(cmp);
    for (int i = 0; i < lists.length; i++) {
    
    
        if (lists[i] != null) {
    
    
            q.add(lists[i]);
        }
    }
    while (!q.isEmpty()) {
    
    
        cur.next = q.poll(); // cur.next指向满足条件的待合并节点
        cur = cur.next; // 更新cur指针,指向最新节点,这时整个链表与弹出的链表是一个整体
        if (cur.next != null) {
    
     // 如果cur.next不为空,将剩余的链表重新加入优先队列
            q.add(cur.next);
        }
    }
    cur.next = null;
    return result.next;
}

Guess you like

Origin blog.csdn.net/u014454538/article/details/90449974