LeetCode 191, 173, 210

文章目录

  • 191. 位1的个数
    • 题目链接
    • 标签
    • 思路
    • 代码
    • Integer.bitCount()
  • 173. 二叉搜索树迭代器
    • 题目链接
    • 标签
    • 思路
      • 递归
      • 迭代
  • 210. 课程表 II
    • 题目链接
    • 标签
    • 思路
    • 代码


191. 位1的个数

题目链接

191. 位1的个数

标签

位运算 分治

思路

这里可以使用一个结论:n & (n - 1) 可以将 n 的二进制数的最后一个 1 变成 0。例如:n = 10,那么 n 的二进制数为 1010n - 1 的二进制数为 1001n & (n - 1) = 1000

利用这个特性,只要 n 不等于 0(即每一位都是 0),就一直进行 n &= n - 1 的操作。记录这个操作的次数,操作次数即为 n 的二进制数中 1 的个数。

代码

class Solution {public int hammingWeight(int n) {int res = 0;while (n != 0) {n &= n - 1;res++;}return res;}
}

Integer.bitCount()

在 Java 中,Integer.bitCount() 静态方法可以完美地处理这个问题,不过它的源码很抽象。

173. 二叉搜索树迭代器

题目链接

173. 二叉搜索树迭代器

标签

栈 树 设计 二叉搜索树 二叉树 迭代器

思路

本题想要实现一个能够返回二叉树的中序遍历的数据结构,中序遍历并不难,可以使用 递归迭代 两种方式,可以看看这道题 94. 二叉树的中序遍历 来学习这两种方式。

递归

先不考虑时间复杂度和空间复杂度,可以在创建本数据结构时,中序遍历传入的二叉树,将结果放到一个链表中,此时,本数据结构就是一个链表

  • 对于 int next() 方法,就像普通链表的 next(),先获取本节点的值,然后让指针指向下一个节点。
  • 对于 boolean hasNext() 方法,就像普通链表的 hasNext(),判断下一个节点是否为 null

以上是传统的 LinkedList(真正的链表)的实现方式,不过,在此处直接使用 ArrayList(更像能够扩容的数组 Vector)更快一点,不仅是从编写代码的角度看,还是从运行的角度看。

  • 对于 int next() 方法,先获取本节点的值,然后让指向元素的索引指向下一个元素。
  • 对于 boolean hasNext() 方法,判断 指向当前元素的索引 是否小于 链表的长度。
class BSTIterator {private int idx = 0; // 指向中序遍历结果链表的索引private List<Integer> list = new ArrayList<>(); // 存放中序遍历的结果public BSTIterator(TreeNode root) {inorderTraversal(root);}public int next() { // 获取当前节点的值,并指向下一个节点return list.get(idx++);}public boolean hasNext() { // 返回当前索引是否小于链表长度return idx < list.size();}private void inorderTraversal(TreeNode curr) { // 中序遍历获取二叉树的所有值if (curr == null) {return;}inorderTraversal(curr.left);list.add(curr.val);inorderTraversal(curr.right);}
}

迭代

在递归的方法中,next(), hasNext() 的时间复杂度都是 O ( 1 ) O(1) O(1),不过使用了 O ( n ) O(n) O(n) 内存,这里的 n 是二叉树的节点个数,明显比二叉树的高度大,所以需要想一种方法来降低空间复杂度。

复习一下中序遍历的思想:先遍历左子树再处理本节点(在本题中是获取本节点的值并返回),最后遍历右子树。这点在代码中会体现到。

这里就想到了中序遍历的迭代实现方式——使用栈

  • 使用 TreeNode curr 记录当前遍历到的节点。
  • 使用 LinkedList<TreeNode> stack 储存未被处理的节点。
  • int next() 方法中,先遍历 curr 的左子树,直到无法再遍历;此时 stack 的栈顶节点就是本次遍历的节点,取出它;最后让 curr 指向本节点的右子节点,准备遍历右子树。
  • boolean hasNext() 方法中,对 当前遍历到的节点 和 储存未被处理的节点的栈 做判断,如果 当前遍历的节点是 null,并且 栈为空,则本二叉树被遍历完了。

看看这种方法的复杂度:

  • 时间复杂度:
    • next():使用 n 次该方法后,总的时间复杂度是 O ( n ) O(n) O(n),平均时间复杂度为 O ( 1 ) O(1) O(1)
    • hasNext():该方法的时间复杂度一直为 O ( 1 ) O(1) O(1)
  • 空间复杂度:栈最多储存的节点数就是二叉树的层数,即为题目所要求的 O ( h ) O(h) O(h),其中,h 是二叉树的高度。
class BSTIterator {private TreeNode curr; // 当前节点private LinkedList<TreeNode> stack = new LinkedList<>(); // 储存节点的栈public BSTIterator(TreeNode root) {curr = root;}public int next() { // 获取当前节点的值,并指向下一个节点// 先遍历左子树while (curr != null) { // 从 curr 开始,一直向左子节点方向遍历,直到 curr 为 nullstack.push(curr);curr = curr.left;}// 再处理本节点curr = stack.pop(); // 取出栈中的最后一个节点,这个节点就是本次遍历的节点int res = curr.val; // 获取节点的值// 最后遍历右子树curr = curr.right; // 指向下一个“节点”:处理完左子节点,该处理右子节点了return res;}public boolean hasNext() { // 只有 栈为空 且 curr 为 null 的情况才算没有下一个节点return !stack.isEmpty() || curr != null;}
}

210. 课程表 II

题目链接

210. 课程表 II

标签

深度优先搜索 广度优先搜索 图 拓扑排序

思路

本题是 207. 课程表 的加强版,但没有加强多少,核心还是 图的拓扑排序入度越小,越靠前。如果对图这个结构不理解,请务必先看 207 题的题解。

拓扑排序的具体步骤为:

  1. 在排序之前,先将所有入度为 0 的结点加入 队列
  2. 将队列中的结点(入度为 0)移出队列。
  3. 把该结点所指向的结点的入度减一。
  4. 当某个结点的入度被减到 0 时,将它加入队列。
  5. 重复第二步到第四步,直到队列为空。

如果需要返回拓扑排序的结果,则在将结点移出队列时,将节点的值加入到结果链表中即可。这也是本题的加强之处。

本题和 207 题一样,难点还在于 如何构建图,思想就是 将图看作 一堆节点 连接的 一堆节点,这里就不做赘述了,看 207 题的题解就行了。

代码

class Solution {public int[] findOrder(int numCourses, int[][] prerequisites) {// 初始化存储图的数据结构List<List<Integer>> graph = new ArrayList<>(numCourses);for (int i = 0; i < numCourses; i++) {graph.add(new ArrayList<>());}// 统计每个结点的入度,并构建图int[] inDegree = new int[numCourses]; // 存储每个结点的入度for (int[] pair : prerequisites) {int start = pair[1]; // 始点int end = pair[0]; // 终点List<Integer> toList = graph.get(start); // 获取 始点的 指向结点集合toList.add(end); // 将 终点 加入 始点的 指向结点集合 中inDegree[end]++; // 让终点的入度加一}// 寻找入度为 0 的结点,初始化队列LinkedList<Integer> queue = new LinkedList<>();for (int i = 0; i < inDegree.length; i++) {if (inDegree[i] == 0) { // 如果索引为 i 的结点的入度为0queue.offer(i); // 则将索引 i 放入队列}}// 拓扑排序int[] res = new int[numCourses]; // 储存结果的数组int cnt = 0; // 结点的索引while (!queue.isEmpty()) { // 直到队列为空才退出循环int start = queue.poll(); // 将结点移出队列,获取始点在graph中的索引res[cnt++] = start; // 将入度为 0 的结点放入结果数组中List<Integer> toList = graph.get(start); // 获取始点指向的所有终点的索引for (int end : toList) { // 将始点指向的所有终点的入度减一if (--inDegree[end] == 0) { // 当终点的入度减到0时queue.offer(end); // 将其加入队列}}}if (cnt != numCourses) { // 如果 移出队列的结点数 不等于 结点总数return new int[0]; // 说明无法学习到全部课程,返回空数组}return res;}
}

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

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

相关文章

天机学堂第二天项目 添加我的课表 项目总结

目录 根据产品原型得到数据库表结构 RabbitMq监听 构造器注入 幂等 mybatisplus 分页查询的多种写法 在new page里面添加排序 查询条件中 用orderBydESC指定排序 ​编辑 链式编程中使用page指定排序 stream流 ​编辑 在网关中解析token 根据产品原型得到数据库表结构 根…

基于物联网的区块链算力网络,IGP/BGP协议

目录 基于物联网的区块链算力网络 IGP/BGP协议 IGP(内部网关协议) BGP(边界网关协议) 内部使用ISP的外部使用BGP的原因 一、网络规模和复杂性 二、路由协议的特性 三、满足业务需求 四、结论 基于物联网的区块链算力网络 通 过 多个物联网传感器将本地计算…

Node服务器开发和部署

Node服务器开发和部署 第一步&#xff1a;写一个Node服务 方法1&#xff1a;Express编写 创建一个项目&#xff1a;node_server mkdir node_server && cd node_server && npm init -y安装express&#xff1a; npm install express至此&#xff0c;项目创建…

使用在UE5中使用AirSim插件Eigen库头文件引用报错,出现报错的解决方式

一、概述 如图所示&#xff0c;用红线圈出的两条头文件引用会报错&#xff0c;提示无法找到他们&#xff0c;但是可以发现的是&#xff0c;他们的路径书写是没有问题的。 // #include <Source/Airlib/deps/eigen3/Eigen/Core> // #include <Source/Airlib/deps/eigen…

Android 线程并发:线程通信:Handler机制

文章目录 API源码分析操作总结 API Handler相关 Handler对象.sendMessage(Message) 发送消息 Handler对象.handleMessage()空方法 自定义Handler重写handleMessage方法&#xff0c;处理Message Looper相关 Looper.getMainLooper() 获取App的UI线程的Looper对象 Looper…

【网络爬虫技术】(1·绪论)

&#x1f308; 个人主页&#xff1a;十二月的猫-CSDN博客 &#x1f525; 系列专栏&#xff1a; &#x1f3c0;网络爬虫开发技术入门_十二月的猫的博客-CSDN博客 &#x1f4aa;&#x1f3fb; 十二月的寒冬阻挡不了春天的脚步&#xff0c;十二点的黑夜遮蔽不住黎明的曙光 目录 …

日拱一卒 | JVM

文章目录 什么是JVM&#xff1f;JVM的组成JVM的大致工作流程JVM的内存模型 什么是JVM&#xff1f; 我们知道Java面试&#xff0c;只要你的简历上写了了解JVM&#xff0c;那么你就必然会被问到以下问题&#xff1a; 什么是JVM&#xff1f;简单说一下JVM的内存模型&#xff1f;…

梯度下降算法,gradient descent algorithm

定义&#xff1a;是一个优化算法&#xff0c;也成最速下降算法&#xff0c;主要的部的士通过迭代找到目标函数的最小值&#xff0c;或者收敛到最小值。 说人话就是求一个函数的极值点&#xff0c;极大值或者极小值 算法过程中有几个超参数&#xff1a; 学习率n&#xff0c;又称…

代码随想录算法训练营第22天-leetcode-回溯算法part01:

#回溯算法理论基础 能解决的问题&#xff1a; 组合问题&#xff1a;N个数里面按一定规则找出k个数的集合切割问题&#xff1a;一个字符串按一定规则有几种切割方式子集问题&#xff1a;一个N个数的集合里有多少符合条件的子集排列问题&#xff1a;N个数按一定规则全排列&…

大数据——HBase原理

摘要 HBase 是一个开源的、非关系型的分布式数据库系统&#xff0c;主要用于存储海量的结构化和半结构化数据。它是基于谷歌的 Bigtable 论文实现的&#xff0c;运行在 Hadoop 分布式文件系统&#xff08;HDFS&#xff09;之上&#xff0c;并且可以与 Hadoop 生态系统的其他组…

太美了!智能汽车触摸屏中控让驾驶员和乘客目不转睛

太美了&#xff01;智能汽车触摸屏中控让驾驶员和乘客目不转睛 引言 艾斯视觉作为行业ui设计和前端开发领域的从业者&#xff0c;其观点始终认为&#xff1a;智能汽车已经成为现代交通的新宠。其中&#xff0c;触摸屏中控系统以其美观、智能、人性化的特点&#xff0c;为驾驶…

Electron的入门介绍与使用React18+Vite+Electron(2)共30节

上一篇讲了如何安装Electron和简单例子&#xff0c;Electron的入门介绍与使用&#xff08;1&#xff09;共30节 让我们回顾一下Electron的发展历史&#xff0c;Electron 最初由 GitHub 公司开发&#xff0c;最早用于构建 GitHub Desktop。随着其成功&#xff0c;Electron 逐渐…

在线投稿小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;编辑管理&#xff0c;用户文章管理&#xff0c;文章分类管理&#xff0c;文章展示管理&#xff0c;文章稿酬管理&#xff0c;通知公告管理&#xff0c;系统管理 微信端账号功能包…

从零开始的Python开发日记(3):Flask框架的使用

最近学会了使用Python的Flask框架&#xff0c;并通过该框架实现API的调用以及转发&#xff0c;以下是flask框架下前后端的数据交互模式 后端&#xff1a;python 的 flask 框架 前端&#xff1a;html、css、js前后端数据交互的方式&#xff1a; 一、前端发送数据&#xff0c;后…

Unity ParticleSystem:创造魔法般的视觉效果

Unity的ParticleSystem是一个功能强大的组件&#xff0c;用于创建各种动态的粒子效果&#xff0c;如火焰、烟雾、雨滴、爆炸等。它不仅可以用于增加游戏的视觉吸引力&#xff0c;还可以用于实现复杂的动画效果。本文将探讨如何使用Unity的ParticleSystem组件来实现动画效果。 …

2022.11.17 阿里钉钉数据开发岗位一面

今天晚上和阿里钉钉面试官聊了一面&#xff0c;整个过程持续45分钟&#xff0c;还是相当持久的。前面先让我自我介绍&#xff0c;包括自身背景、工作经历和项目经验&#xff0c;在介绍的时候面试官几次打断&#xff0c;让我停下来&#xff0c;然后他提问&#xff0c;我很纳闷还…

59 阻塞和非阻塞IO

阻塞式io 一个简单的用户输入回显功能&#xff0c;在用户未输入内容时&#xff0c;会一直阻塞住 #include <iostream> #include <unistd.h>using namespace std; int main() {char buff[1024];while (true){cout << "please enter ";fflush(stdo…

VAD: 向量化场景表示,用于高效的自动驾驶

VAD: Vectorized Scene Representation for Efficient Autonomous Driving VAD: 向量化场景表示&#xff0c;用于高效的自动驾驶 https://github.com/hustvl/VAD Abstract Autonomous driving requires a comprehensive understanding of the surrounding environment for …

英语单词终极记忆

你应当知道一个专业术语&#xff0c;叫COCA。 这个单词很好记&#xff0c;但你可能记不住。 你应当这样记&#xff1a; 你记住了 可口可乐&#xff0c;也就记住了 coca &#xff08;谐音&#xff1a;可口&#xff09;。 从而记住了 COCA。 无论如何&#xff0c;你这辈子&…

react版本判断是否面包含

react-admin: react版本 import { useState,useEffect } from react import ./Secene.css import { Checkbox } from "antd"; import* as turf from turf/turf; import type { CheckboxProps } from antd; // const onChange: CheckboxProps[onChange] (e) >…