09/05 🔥 LeetCode 热题 HOT 100 -- 22, 23,31

22. 括号生成

class Solution {
    public List<String> generateParenthesis(int n) {
        List<String> result = new ArrayList<>();
        generateParenthesisHelper(n, n, "", result);
        return result;
    }

    private void generateParenthesisHelper(int leftNeeded, int rightNeeded, String currentString, List<String> result) {
        // 递归终止条件
        if (leftNeeded == 0 && rightNeeded == 0) {
            result.add(currentString);
            return;
        }

        // 只有当左边需要的括号>0才加
        if (leftNeeded > 0) {
            generateParenthesisHelper(leftNeeded - 1, rightNeeded, currentString + "(", result);
        }

        if (leftNeeded < rightNeeded) {
            generateParenthesisHelper(leftNeeded, rightNeeded - 1, currentString + ")", result);
        }
    }
}

23. 合并K个升序链表

解法一: 每次合并两个链表

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode mergeKLists(ListNode[] lists) {
        if (lists == null || lists.length == 0) {
            return null;
        }

        ListNode merged = lists[0];

        for (int i = 1; i < lists.length; i++) {
            merged = mergeTwoLists(merged, lists[i]);
        }

        return merged;
    }

    private ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        if (l1 == null && l2 == null) {
            return null;
        }

        ListNode dummyHead = new ListNode(-1);
        ListNode p = dummyHead;
        while (l1 != null && l2 != null) {
            if (l1.val < l2.val) {
                p.next = l1;
                l1 = l1.next;
            } else {
                p.next = l2;
                l2 = l2.next;
            }
            p = p.next;
        }

        p.next = l1 == null ? l2 : l1;
        return dummyHead.next;
    }
}

解法二:利用优先队列对所有元素一次合并

class Solution {
    public ListNode mergeKLists(ListNode[] lists) {
        if (lists == null || lists.size() == 0) {
            return null;
        }
        if (lists.length == 1) {
            return lists[0];
        }

        PriorityQueue<ListNode> pq = new PriorityQueue<>((l1, l2)->l1.val - l2.val);
        for (ListNode i : lists) {
            if (i != null) {
                pq.offer(i);
            }
        }

        ListNode head = new ListNode(-1);
        ListNode prev = head;
        while (!pq.isEmpty()) {
            ListNode node = pq.poll();
        // 先指定当前指针位置的下一节点,然后移动指针到下一节点
            prev.next = node;
            prev = prev.next;
            if (node.next != null) {
                pq.offer(node.next);
            }
        }

        return head.next;
    }
}

31. 下一个排列

class Solution {
    public void nextPermutation(int[] nums) {
        int i = nums.length - 2;
        // i = 3
        // 找到后面数字递减开始的位置,即找到左边尽量靠右的较小的数
        // [1, 4, 5, 3, 1]
        while (i >= 0 && nums[i + 1] <= nums[i]) { // nums[1 + 1] > nums[1], 跳出
            i--;
        }
        // i = 1

        if (i >= 0) {
            // 找到i右边比nums[i]大的数
            int j = nums.length - 1; // j = 4
            while (j >= i && nums[j] <= nums[i]) { // nums[2] > nums[1], 跳出
                j--;
            }
            // j = 2

            swap(i, j, nums);
        }
        // [1, 5, 4, 3, 1]

        // Reverse all the numbers after i
        int start = i + 1; // start = 2

        reverse(nums, start);
        // [1, 5, 1, 3, 4]
    }

    private void swap(int i, int j, int[] nums) {
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }

    private void reverse(int[] nums, int start) {
        int end = nums.length - 1;
        while (start < end) {
            swap(start, end, nums);
            start++;
            end--;
        }
    }
}
}
本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!