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

news2024/11/19 23:29:15

目录

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.

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;
    }
}

时间: 击败了100.00%

内存: 击败了49.75%

 148.排序链表

题意:

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

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

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

解题思路:

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

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

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

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

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;
        
    }
}

时间: 击败了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,继续调用递归函数判断。

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;
    }
};
*/

时间: 击败了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. 将两个排序后的子链表数组合并,得到完成的排列后的链表。

/**
 * 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;
    }


}

时间: 击败了100.00%

内存: 击败了57.58%

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1000978.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何实现自己在家搭建全端口P2P穿透?快解析内网穿透

对于有公网主机&#xff0c;有一定的操作能力&#xff0c;需要独立资源配置使用的&#xff0c;可以选择自行搭建内网映射服务。那么如何实现自己搭建全端口P2P穿透呢&#xff1f;下面为大家提供了不同场景下的不同方法&#xff0c;供大家使用时参考。 SSH是一种安全的远程登录…

一个方法用js生成随机双色球、大乐透

代码如下&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title><s…

【C++】构造函数分类 ① ( 构造函数分类简介 | 无参构造函数 | 有参构造函数 | 拷贝构造函数 | 代码示例 - 三种类型构造函数定义与调用 )

文章目录 一、构造函数分类1、构造函数分类简介2、构造函数分类代码分析无参构造函数有参构造函数拷贝构造函数 二、代码示例 - 三种类型构造函数定义与调用 一、构造函数分类 1、构造函数分类简介 C 构造函数可以分为以下几类 : 无参构造函数 : 最简单也是默认的构造函数 , 函…

gitlab在项目中创建自己的分支的顺序操作,一整套流程

gitlab在项目中创建自己的分支的顺序操作&#xff0c;一整套流程 目录概述需求&#xff1a; 设计思路实现思路分析 参考资料和推荐阅读 Survive by day and develop by night. talk for import biz , show your perfect code,full busy&#xff0c;skip hardness,make a better…

【C++】day4学习成果:仿写string类等等

1.仿照string类&#xff0c;完成myString 类 代码&#xff1a; #include <iostream> #include <cstring>using namespace std;class myString {private:char *str; //记录c风格的字符串int size; //记录字符串的实际长度public://无参构造myS…

C++学习之list的实现

在了解学习list实现之前我们首先了解一下关于迭代器的分类&#xff1a; 按功能分类&#xff1a; 正向迭代器 反向迭代器 const正向迭代器 const反向迭代器 按性质分类&#xff1a; 单向迭代器 只能 例如单链表 双向迭代器 可&#xff0c;也可-- 例如双…

酒店固定资产管理怎么分类

在酒店业中&#xff0c;固定资产的管理是至关重要的一环。它不仅影响到企业的运营效率和盈利能力&#xff0c;而且直接影响到客户体验和品牌形象。因此&#xff0c;对于酒店管理者来说&#xff0c;合理、有效地进行固定资产管理是一项必不可少的任务。本文将探讨酒店固定资产的…

Spring系列文章:Bean的获取⽅式

一、简介 Spring为Bean提供了多种实例化⽅式&#xff0c;通常包括4种⽅式。&#xff08;也就是说在Spring中为Bean对象的创建准 备了多种⽅案&#xff0c;⽬的是&#xff1a;更加灵活&#xff09; 第⼀种&#xff1a;通过构造⽅法实例化 第⼆种&#xff1a;通过简单⼯⼚模式…

c++day4---9.11

1.思维导图&#xff1a; 2.myString: #include <iostream> #include <cstring> #include <cstdlib>using namespace std;class myString { private:char *str; //记录c风格的字符串int size; //记录字符串的实际长度 public://无参构造m…

springboot之二:整合junit进行单元测试+整合redis(本机、远程)+整合mybatis

资源地址&#xff1a; 整合junit的代码&#xff1a;https://download.csdn.net/download/zhiaidaidai/88291527 整合redis的代码&#xff1a;https://download.csdn.net/download/zhiaidaidai/88291536 整合mybatis的代码&#xff1a;https://download.csdn.net/download/zh…

科研绘图,别忘Origin!

公众号&#xff1a;尤而小屋作者&#xff1a;Peter编辑&#xff1a;Peter 大家好&#xff0c;我是Peter~ 科研绘图&#xff0c;你一般用什么软件&#xff1a; Python&#xff1f;R&#xff1f;MATLAB&#xff1f;GraphPad Prism&#xff1f;Matplotlib&#xff1f; 但&#…

案例:实现TodoLis(尚硅谷)

是做完后再记录的&#xff0c;前端我主要是要了解下&#xff0c;所以这里记录的比较浅 由于是做完后记录&#xff0c;所以你cv后的代码的效果并不一定和我展示的效果图一样 静态页面 先来实现静态页面&#xff0c;再考虑动态页面 组件拆分 说明(实际的组件名不是和下面一样的…

记录第一次带后端团队

在过去的一个半月里我第一次作为后端开发组长角色参与公司项目从0到1的开发&#xff0c;记录这一次开发的经历。 1、背景介绍 首先说明一下背景。我所在的公司是做智慧社区相关业务&#xff0c;开发的项目是系统升级工具&#xff0c;方便公司实施同事安装和升级系统。 参与后…

安全可靠的文件传输服务助力完成更高效的医疗保健工作(下)

医疗保健事业是关乎人类健康和社会发展的重要领域&#xff0c;它需要依赖海量的医疗数据&#xff0c;如病人信息、医疗影像、化验结果、电子病历、诊断建议等。这些数据不仅关系到病人的个人利益和医疗质量&#xff0c;也关系到医院的运行效率和医疗水平。因此&#xff0c;如何…

荣耀崛起礼包码2023,荣耀崛起攻略

荣耀崛起是一款传统的卡牌手游&#xff0c;它将区域探索游戏无缝集成到卡牌游戏中。相信很多玩家都很好奇&#xff0c;荣耀崛起礼包码2023是什么&#xff1f;有没有给新手的一些攻略建议呢&#xff1f;下面小编就和大家简单分享一下&#xff0c;感兴趣的朋友&#xff0c;一起来…

uni-app(微信小程序)图片旋转放缩,文字绘制、海报绘制

总结一下&#xff1a; 要进行海报绘制离不开canvas&#xff0c;我们是先进行图片&#xff0c;文字的拖拽、旋转等操作 最后再对canvas进行绘制&#xff0c;完成海报绘制。 背景区域设置为 position: relative&#xff0c;方便图片在当前区域中拖动等处理。添加图片&#xff0…

一文掌握SSD、EMMC、UFS原理与差异

有一天&#xff0c;小明在他的智能手机上播放了一段高清视频&#xff0c;发现视频播放得非常流畅。他感叹道&#xff1a;“现在的存储技术真是太棒了&#xff01;”他的朋友小华却告诉他&#xff1a;“这还不算什么&#xff0c;你还没用过UFS呢&#xff01;”小明一下子好奇起来…

【Spring Cloud系统】- 轻量级高可用工具Keepalive详解

【Spring Cloud系统】- 轻量级高可用工具Keepalive详解 文章目录 【Spring Cloud系统】- 轻量级高可用工具Keepalive详解一、概述二、Keepalive分类2.1 TCP的keepalive2.2 HTTP的keep-alive2.3 TCP的 KeepAlive 和 HTTP的 Keep-Alive区别 三、nginx的keepalive配置3.1 nginx保持…

初出茅庐的小李博客之根据编译时间生成软件版本号

为什么要软件版本号呢&#xff1f; 生成软件版本号是在软件开发和维护过程中非常重要的一项任务&#xff0c;它有很多意义和好处&#xff0c;同时也有多种常见的方法。 标识和追踪&#xff1a;软件版本号是唯一的标识符&#xff0c;用于区分不同版本的软件。这有助于开发人员和…

【案例分享】部署华为防火墙确保园区出口安全

【微|信|公|众|号&#xff1a;厦门微思网络】 部署华为防火墙确保园区出口安全案例 本案例将以园区典型组网为例&#xff0c;主要介绍园区出口安全的部署。具体业务安全要求如下&#xff1a; 内网用户可以正常访问Internet资源&#xff0c;但只能访问教育/科学类、搜索/门户类网…