• 【LeetCode-面试经典150题-day23】


    目录

    108. 将有序数组转换为二叉搜索树

     148.排序链表

     427.建立四叉树

     23.合并K个升序链表


     

    108. 将有序数组转换为二叉搜索树

    题意:

    给你一个整数数组 nums ,其中元素已经按 升序 排列,请你将其转换为一棵 高度平衡 二叉搜索树

    高度平衡 二叉树是一棵满足「每个节点的左右两个子树的高度差的绝对值不超过 1 」的二叉树。

    【输入样例】nums = [-10,-3,0,5,9]

    【输出样例】[0,-3,9,-10,null,5] 或 [0,-10,5,null,-3,null,9]

     
     

    解题思路:

    二叉搜索树进行中序遍历的时候,得到的序列是升序序列,因此我们可以将给定的序列作为中序遍历的结果,来构建二叉搜索树;

    左右两棵子树高度差绝对值不超过1,则考虑将中间位置的数字作为根节点(向下取整),mid=(left+right)/2.

    1. class Solution {
    2. public TreeNode sortedArrayToBST(int[] nums) {
    3. return helper(nums, 0, nums.length - 1);
    4. }
    5. public TreeNode helper(int[] nums, int left, int right){
    6. if(left > right){
    7. return null;
    8. }
    9. //总是选择中间位置左边的数字作为根节点
    10. int mid = (left + right) /2;
    11. TreeNode root = new TreeNode(nums[mid]);
    12. root.left = helper(nums, left, mid - 1);
    13. root.right = helper(nums, mid+1, right);
    14. return root;
    15. }
    16. }

    时间: 击败了100.00%

    内存: 击败了49.75%

     148.排序链表

    题意:

    给你链表的头结点 head ,请将其按 升序 排列并返回 排序后的链表 。

    【输入样例】head = [4,2,1,3]

    【输出样例】[1,2,3,4]

    解题思路:

    使用排序算法即可,这边我们使用自顶向下归并排序。

    1.每次找到链表中点,将链表拆分成两个子链表。链表无法像数组一样直接根据下标找到中点,我们可以使用快慢指针,快指针移动2步,慢指针移动1步。当快指针到链表末尾时,慢指针所指的就是中点。

    2.分别对两个子链表进行排序

    3. 将两个排序后的子链表合并,得到完成的排列后的链表。

    1. class Solution {
    2. public ListNode sortList(ListNode head) {
    3. return mergeSort(head,null);
    4. }
    5. //tail是指最后一个节点的下一节点,在样例中是节点3的next,所以主函数调用时传过来的是null
    6. public ListNode mergeSort(ListNode head, ListNode tail){
    7. if(head == null){
    8. //链表为空
    9. return head;
    10. }
    11. if(head.next == tail){
    12. //链表中只包含head一个节点
    13. head.next = null;
    14. return head;
    15. }
    16. //快慢指针寻找中点
    17. ListNode slow = head,fast = head;
    18. while(fast != tail){
    19. slow = slow.next;
    20. fast = fast.next;
    21. //快指针一次走两步,当走完第一步后,又可能已经走到尾节点,此时就不需要再走第二步了
    22. if(fast != tail){
    23. fast = fast.next;
    24. }
    25. }
    26. ListNode mid = slow;
    27. ListNode list1 = mergeSort(head,mid);
    28. ListNode list2 = mergeSort(mid,tail);
    29. ListNode sorted = merge(list1,list2);
    30. return sorted;
    31. }
    32. public ListNode merge(ListNode list1, ListNode list2){
    33. ListNode dummyHead = new ListNode(0);
    34. ListNode temp = dummyHead,temp1 = list1,temp2 = list2;
    35. while(temp1 != null && temp2 != null){
    36. if(temp1.val <= temp2.val){
    37. temp.next = temp1;
    38. temp1 = temp1.next;
    39. }else{
    40. temp.next = temp2;
    41. temp2 = temp2.next;
    42. }
    43. temp = temp.next;
    44. }
    45. if (temp1 != null) {
    46. temp.next = temp1;
    47. } else if (temp2 != null) {
    48. temp.next = temp2;
    49. }
    50. return dummyHead.next;
    51. }
    52. }

    时间: 击败了56.72%

    内存: 击败了21.21%

     427.建立四叉树

    题意:

    给你一个 n * n 矩阵 grid ,矩阵由若干 0 和 1 组成。请你用四叉树表示该矩阵 grid 。

    你需要返回能表示矩阵 grid 的 四叉树 的根结点。

    四叉树数据结构中,每个内部节点只有四个子节点。此外,每个节点都有两个属性:

    • val:储存叶子结点所代表的区域的值。1 对应 True,0 对应 False。注意,当 isLeaf 为 False 时,你可以把 True 或者 False 赋值给节点,两种值都会被判题机制 接受 。
    • isLeaf: 当这个节点是一个叶子结点时为 True,如果它有 4 个子节点则为 False 。
    class Node {
        public boolean val;
        public boolean isLeaf;
        public Node topLeft;
        public Node topRight;
        public Node bottomLeft;
        public Node bottomRight;
    }

    我们可以按以下步骤为二维区域构建四叉树:

    1. 如果当前网格的值相同(即,全为 0 或者全为 1),将 isLeaf 设为 True ,将 val 设为网格相应的值,并将四个子节点都设为 Null 然后停止。
    2. 如果当前网格的值不同,将 isLeaf 设为 False, 将 val 设为任意值,然后如下图所示,将当前网格划分为四个子网格。
    3. 使用适当的子网格递归每个子节点。

    【输入样例】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]]

    【输出样例】[[0,1],[1,1],[0,1],[1,1],[1,0],null,null,null,null,[1,0],[1,0],[1,1],[1,1]]

    解题思路:

    1. 使用递归函数判断区域(r0,r1,c0,c1)内的值是否为全0或全1,如果是,这一部分为叶子节点,构造出节点后return,因为叶节点不需要再遍历;如果不是,构造一个非叶节点,之后将其划分为四个子区域,行的分界线是(r0+r1)/2,列的分界线是(c0+c1)/2,继续调用递归函数判断。

    1. class Solution {
    2. public Node construct(int[][] grid) {
    3. return findLeaf(grid, 0, grid.length, 0, grid.length);
    4. }
    5. public Node findLeaf(int[][] grid, int r0, int r1, int c0, int c1){
    6. boolean same = true;
    7. for(int i=r0; i < r1; i++){
    8. for(int j=c0; j< c1; j++){
    9. if(grid[i][j] != grid[r0][c0]){
    10. //不是叶子节点,直接跳出就可以了,只能跳出j循环
    11. same = false;
    12. break;
    13. }
    14. }
    15. //跳出i循环
    16. if(!same){
    17. break;
    18. }
    19. }
    20. if(same){
    21. //叶子节点,构造,return
    22. return new Node(grid[r0][c0] == 1,true);
    23. }
    24. Node ret = new Node(
    25. true,//值默认给true
    26. false,//不是叶子节点
    27. findLeaf(grid, r0, (r0+r1)/2, c0, (c0+c1)/2),
    28. findLeaf(grid, r0, (r0+r1)/2, (c0+c1)/2, c1),
    29. findLeaf(grid, (r0+r1)/2, r1, c0, (c0+c1)/2),
    30. findLeaf(grid, (r0+r1)/2, r1, (c0+c1)/2, c1)
    31. );
    32. return ret;
    33. }
    34. }
    35. /*
    36. // Definition for a QuadTree node.
    37. class Node {
    38. public boolean val;
    39. public boolean isLeaf;
    40. public Node topLeft;
    41. public Node topRight;
    42. public Node bottomLeft;
    43. public Node bottomRight;
    44. public Node() {
    45. this.val = false;
    46. this.isLeaf = false;
    47. this.topLeft = null;
    48. this.topRight = null;
    49. this.bottomLeft = null;
    50. this.bottomRight = null;
    51. }
    52. public Node(boolean val, boolean isLeaf) {
    53. this.val = val;
    54. this.isLeaf = isLeaf;
    55. this.topLeft = null;
    56. this.topRight = null;
    57. this.bottomLeft = null;
    58. this.bottomRight = null;
    59. }
    60. public Node(boolean val, boolean isLeaf, Node topLeft, Node topRight, Node bottomLeft, Node bottomRight) {
    61. this.val = val;
    62. this.isLeaf = isLeaf;
    63. this.topLeft = topLeft;
    64. this.topRight = topRight;
    65. this.bottomLeft = bottomLeft;
    66. this.bottomRight = bottomRight;
    67. }
    68. };
    69. */

    时间: 击败了100.00%

    内存: 击败了26.98%

     23.合并K个升序链表

    题意:

    给你一个链表数组,每个链表都已经按升序排列。

    请你将所有链表合并到一个升序链表中,返回合并后的链表。

    【输入样例】lists = [[1,4,5],[1,3,4],[2,6]]

    【输出样例】[1,1,2,3,4,4,5,6]

    解题思路:

    使用排序算法即可,这边我们使用自顶向下归并排序。

    1.每次找到链表数组中点,将链表数组拆分成两个子链表数组。

    2.分别对两个子链表数组进行排序

    3. 将两个排序后的子链表数组合并,得到完成的排列后的链表。

    1. /**
    2. * Definition for singly-linked list.
    3. * public class ListNode {
    4. * int val;
    5. * ListNode next;
    6. * ListNode() {}
    7. * ListNode(int val) { this.val = val; }
    8. * ListNode(int val, ListNode next) { this.val = val; this.next = next; }
    9. * }
    10. */
    11. class Solution {
    12. public ListNode mergeKLists(ListNode[] lists) {
    13. return mergeLists(lists, 0, lists.length-1);
    14. }
    15. public ListNode mergeLists(ListNode[] lists, int start, int end){
    16. if(start == end){
    17. return lists[start];
    18. }
    19. if(start > end){
    20. return null;
    21. }
    22. int mid = (start + end) / 2;
    23. return merge(mergeLists(lists, start, mid), mergeLists(lists, mid+1, end));
    24. }
    25. public ListNode merge(ListNode a, ListNode b){
    26. if( a== null || b == null){
    27. return a != null ? a : b;
    28. }
    29. ListNode head = new ListNode(0);
    30. ListNode tail = head, temp1 = a, temp2 = b;
    31. while(temp1 != null && temp2 != null){
    32. if(temp1.val <= temp2.val){
    33. tail.next = temp1;
    34. temp1 = temp1.next;
    35. }else{
    36. tail.next = temp2;
    37. temp2 = temp2.next;
    38. }
    39. tail = tail.next;
    40. }
    41. tail.next = (temp1 != null ? temp1 : temp2);
    42. return head.next;
    43. }
    44. }

    时间: 击败了100.00%

    内存: 击败了57.58%

  • 相关阅读:
    嵌入式系统的应用与发展
    最近面了12个人,发现这个测试基础题都答不上来...
    无风扇嵌入式车载电脑在矿山车辆行业应用
    预测房屋价格(使用SGDRegressor随机梯度下降回归)
    C# string和MemoryStream及byte[]之间相互转换
    [Vue3]构建通用后台系统
    Jenkins一站成魔【1】传统安装与说明
    .net入行三年的感想回顾
    2023最新SSM计算机毕业设计选题大全(附源码+LW)之java高校学生宿舍管理信息系统3x4rz
    Linux下的命令行参数和环境变量
  • 原文地址:https://blog.csdn.net/qq_37998848/article/details/132800069