[LeetCode-150 classic interview questions-day23]

Table of contents

108. Convert ordered array to binary search tree

 148. Sorted linked list

 427.Build a quadtree

 23. Merge K ascending linked lists


 

108. Convert ordered array to binary search tree

Question meaning:

You are given an array of integers  nums in which the elements are sorted in  ascending  order. Please convert it into a  height-balanced  binary search tree.

A height-balanced  binary tree is a binary tree that satisfies "the absolute value of the height difference between the left and right subtrees of each node does not exceed 1".

[Input example] nums = [-10,-3,0,5,9]

[Output sample] [0,-3,9,-10,null,5] or [0,-10,5,null,-3,null,9]

 
  

Problem-solving ideas:

When a binary search tree performs in-order traversal, the sequence obtained is an ascending sequence, so we can use the given sequence as the result of in-order traversal to construct a binary search tree;

If the absolute value of the height difference between the left and right subtrees does not exceed 1, then the number in the middle position is considered as the root node (rounded down), mid=(left+right)/2.

class Solution {
    public TreeNode sortedArrayToBST(int[] nums) {
        return helper(nums, 0, nums.length - 1);
    }

    public TreeNode helper(int[] nums, int left, int right){
        if(left > right){
            return null;
        }

        //总是选择中间位置左边的数字作为根节点
        int mid = (left + right) /2;
        TreeNode root = new TreeNode(nums[mid]);
        root.left = helper(nums, left, mid - 1);
        root.right = helper(nums, mid+1, right);
        return root;
    }
}

Time: Beat 100.00%

Memory: Beaten by 49.75%

 148. Sorted linked list

Question meaning:

Given the head node of the linked list  head , please sort it in ascending  order  and return  the sorted linked list  .

[Input example] head = [4,2,1,3]

[Output sample][1,2,3,4]

Problem-solving ideas:

Just use the sorting algorithm. Here we use top-down merge sorting.

1. Every time the midpoint of the linked list is found, split the linked list into two sub-linked lists. A linked list cannot find the midpoint directly based on the subscript like an array. We can use fast and slow pointers. The fast pointer moves 2 steps and the slow pointer moves 1 step. When the fast pointer reaches the end of the linked list, the slow pointer points to the midpoint.

2. Sort the two sub-linked lists separately

3. Merge the two sorted sub-linked lists to obtain the completed sorted linked list.

class Solution {
    public ListNode sortList(ListNode head) {
        return mergeSort(head,null);
    }

    //tail是指最后一个节点的下一节点,在样例中是节点3的next,所以主函数调用时传过来的是null
    public ListNode mergeSort(ListNode head, ListNode tail){
        if(head == null){
            //链表为空
            return head;
        }
        if(head.next == tail){
            //链表中只包含head一个节点
            head.next = null;
            return head;
        }
        //快慢指针寻找中点
        ListNode slow = head,fast = head;
        while(fast != tail){
            slow = slow.next;
            fast = fast.next;
            //快指针一次走两步,当走完第一步后,又可能已经走到尾节点,此时就不需要再走第二步了
            if(fast != tail){
                fast = fast.next;
            }
        }
        ListNode mid = slow;
        ListNode list1 = mergeSort(head,mid);
        ListNode list2 = mergeSort(mid,tail);
        ListNode sorted = merge(list1,list2);
        return sorted;
    }

    public ListNode merge(ListNode list1, ListNode list2){
        ListNode dummyHead = new ListNode(0);
        ListNode temp = dummyHead,temp1 = list1,temp2 = list2;

        while(temp1 != null && temp2 != null){
            if(temp1.val <= temp2.val){
                temp.next = temp1;
                temp1 = temp1.next;
            }else{
                temp.next = temp2;
                temp2 = temp2.next;
            }
            temp = temp.next;
        }
        if (temp1 != null) {
            temp.next = temp1;
        } else if (temp2 != null) {
            temp.next = temp2;
        }
        return dummyHead.next;
        
    }
}

Time: Defeated 56.72%

Memory: Beaten by 21.21%

 427.Build a quadtree

Question meaning:

You are given a  n * n matrix  grid , which consists of several  0 sums  1 . Please use a quadtree to represent this matrix  grid .

grid You need to return the root node of the quadtree that represents the matrix  .

In the quadtree data structure, each internal node has only four child nodes. Additionally, each node has two properties:

  • val: Stores the value of the area represented by the leaf node. 1 corresponds to  True , 0 corresponds to  False . Note that when  isLeaf it is  False  , you can assign  True  or  False to the node, and both values ​​will be accepted  by the question mechanism   .
  • isLeaf: True when this node is a leaf node  , False if it has 4 child nodes   .
class Node {
    public boolean val;
    public boolean isLeaf;
    public Node topLeft;
    public Node topRight;
    public Node bottomLeft;
    public Node bottomRight;
}

We can build a quadtree for a two-dimensional region by following these steps:

  1. If the values ​​of the current grid are the same (that is, all  0 or all  1), it will  isLeaf be set to True,  val the corresponding value of the grid will be set, and all four child nodes will be set to Null and then stop.
  2. If the values ​​of the current grid are different, it will  isLeaf be set to False, it will  val be set to any value, and then the current grid will be divided into four sub-grids as shown below.
  3. Recurse each child node using the appropriate subgrid.

[Input example] grid = [[1,1,1,1,0,0,0,0],[1,1,1,1,0,0,0,0],[1,1,1 ,1,1,1,1,1],[1,1,1,1,1,1,1,1],[1,1,1,1,0,0,0,0],[1 ,1,1,1,0,0,0,0],[1,1,1,1,0,0,0,0],[1,1,1,1,0,0,0,0 ]]

[Output sample][[0,1],[1,1],[0,1],[1,1],[1,0],null,null,null,null,[1,0], [1,0],[1,1],[1,1]]

Problem-solving ideas:

1. Use a recursive function to determine whether the values ​​in the area (r0, r1, c0, c1) are all 0 or all 1. If so, this part is a leaf node. Return after constructing the node, because the leaf node does not need to be traversed again; If not, construct a non-leaf node, and then divide it into four sub-areas. The dividing line of the row is (r0+r1)/2, and the dividing line of the column is (c0+c1)/2. Continue to call the recursive function to judge.

class Solution {
    public Node construct(int[][] grid) {
        return findLeaf(grid, 0, grid.length, 0, grid.length);
    }
    public Node findLeaf(int[][] grid, int r0, int r1, int c0, int c1){
        boolean same = true;
        for(int i=r0; i < r1; i++){
            for(int j=c0; j< c1; j++){
                if(grid[i][j] != grid[r0][c0]){
                    //不是叶子节点,直接跳出就可以了,只能跳出j循环
                    same = false;
                    break;
                }
            }
            //跳出i循环
            if(!same){
                break;
            }
        }

        if(same){
            //叶子节点,构造,return
            return new Node(grid[r0][c0] == 1,true);
        }

        Node ret = new Node(
            true,//值默认给true
            false,//不是叶子节点
            findLeaf(grid, r0, (r0+r1)/2, c0, (c0+c1)/2),
            findLeaf(grid, r0, (r0+r1)/2, (c0+c1)/2, c1),
            findLeaf(grid, (r0+r1)/2, r1, c0, (c0+c1)/2),
            findLeaf(grid, (r0+r1)/2, r1, (c0+c1)/2, c1)
        );
        return ret;
    }
}

/*
// Definition for a QuadTree node.
class Node {
    public boolean val;
    public boolean isLeaf;
    public Node topLeft;
    public Node topRight;
    public Node bottomLeft;
    public Node bottomRight;

    
    public Node() {
        this.val = false;
        this.isLeaf = false;
        this.topLeft = null;
        this.topRight = null;
        this.bottomLeft = null;
        this.bottomRight = null;
    }
    
    public Node(boolean val, boolean isLeaf) {
        this.val = val;
        this.isLeaf = isLeaf;
        this.topLeft = null;
        this.topRight = null;
        this.bottomLeft = null;
        this.bottomRight = null;
    }
    
    public Node(boolean val, boolean isLeaf, Node topLeft, Node topRight, Node bottomLeft, Node bottomRight) {
        this.val = val;
        this.isLeaf = isLeaf;
        this.topLeft = topLeft;
        this.topRight = topRight;
        this.bottomLeft = bottomLeft;
        this.bottomRight = bottomRight;
    }
};
*/

Time: Beat 100.00%

Memory: Beaten by 26.98%

 23. Merge K ascending linked lists

Question meaning:

You are given an array of linked lists, each linked list has been sorted in ascending order.

Please merge all linked lists into an ascending linked list and return the merged linked list.

[Input example] lists = [[1,4,5],[1,3,4],[2,6]]

[Output sample][1,1,2,3,4,4,5,6]

Problem-solving ideas:

Just use the sorting algorithm. Here we use top-down merge sorting.

1. Each time the midpoint of the linked list array is found, split the linked list array into two sub-linked list arrays.

2. Sort the two sub-linked list arrays respectively

3. Merge the two sorted sub-linked list arrays to obtain the completed arranged linked list.

/**
 * 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 mergeKLists(ListNode[] lists) {
        return mergeLists(lists, 0, lists.length-1);
    }

    public ListNode mergeLists(ListNode[] lists, int start, int end){
        if(start == end){
            return lists[start];
        }
        if(start > end){
            return null;
        }
        int mid = (start + end) / 2;
        return merge(mergeLists(lists, start, mid), mergeLists(lists, mid+1, end));
    }

    public ListNode merge(ListNode a, ListNode b){
        if( a== null || b == null){
            return a != null ? a : b;
        }
        ListNode head = new ListNode(0);
        ListNode tail = head, temp1 = a, temp2 = b;
        while(temp1 != null && temp2 != null){
            if(temp1.val <= temp2.val){
                tail.next = temp1;
                temp1 = temp1.next;
            }else{
                tail.next = temp2;
                temp2 = temp2.next;
            }
            tail = tail.next;
        }
        tail.next = (temp1 != null ? temp1 : temp2);
        return head.next;
    }


}

Time: Beat 100.00%

Memory: Beaten by 57.58%

Guess you like

Origin blog.csdn.net/qq_37998848/article/details/132800069