J20250704 算法题5道

题目一览:

606. 根据二叉树创建字符串 - 力扣(LeetCode)

506. 相对名次 - 力扣(LeetCode)

1. 两数之和 - 力扣(LeetCode)

100. 相同的树 - 力扣(LeetCode)

101. 对称二叉树 - 力扣(LeetCode)

这是周一截止到今天周五的,这次选的题目都比较简单。大部分都和二叉树用dfs解题有关(因为前一整子学了这些,刚好就再写一遍),有一道是关于最近学的堆排序。

题解:

1. 根据二叉树创建字符串

给你二叉树的根节点 root ,请你采用前序遍历的方式,将二叉树转化为一个由括号和整数组成的字符串,返回构造出的字符串。

空节点使用一对空括号对 "()" 表示,转化后需要省略所有不影响字符串与原始二叉树之间的一对一映射关系的空括号对。

解:这道题的关键是明白什么时候存放root.val,什么时候存放  “()”“( ”  “  )”

1)创建StringBuilde类型的对象stringbuilder,之后得到结果都可以通过append操作一步步添加到stringbuilder中。

2)遍历二叉树(递归): 

a. 需要分别判断左子树和右子树的情况,当 root 不为空,则将 root.val 放到stringbuilder中。

b. 再去看左子树情况 ——> 判断 root.left 是否为空,不为空就将“( ” 放到stringbuilder中,代表有左子树,再将左子树的根放入函数进行递归,重复上面的操作。而如果 root.left 为空,就需要判断右子树,右子树也为空,则直接返回,不为空则将“()” 放入stringbuilder再返回。

c. 判断右子树的情况的代码逻辑则和左子树一致。唯一不同的是如果判断右子树为空的话,不用再去判断左子树是否为空,而是直接返回

d. 最后得到结果stringbuilder,输出即可

注意:在每次递归返回时,“ )”都会放入stringbuilder。不需要在其他地方再加多余的 “)”。(不太明白的话可以看看代码理解)

代码:

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode() {}*     TreeNode(int val) { this.val = val; }*     TreeNode(int val, TreeNode left, TreeNode right) {*         this.val = val;*         this.left = left;*         this.right = right;*     }* }*/
class Solution {public String tree2str(TreeNode root) { StringBuilder stringBuilder = new StringBuilder();tree2strChild(root,stringBuilder);return stringBuilder.toString();}public void tree2strChild(TreeNode root,StringBuilder stringBuilder){if(root == null){return;}stringBuilder.append(root.val);//判断左子树的情况if(root.left!=null){stringBuilder.append("(");tree2strChild(root.left,stringBuilder);stringBuilder.append(")");}else{if(root.right!=null){stringBuilder.append("()");}else{return;}}//判断右子树的情况if(root.right!=null){stringBuilder.append("(");tree2strChild(root.right,stringBuilder);stringBuilder.append(")");} else{return;}}
}

2. 相对名次

给你一个长度为 n 的整数数组 score ,其中 score[i] 是第 i 位运动员在比赛中的得分。所有得分都 互不相同 。

运动员将根据得分 决定名次 ,其中名次第 1 的运动员得分最高,名次第 2 的运动员得分第 2 高,依此类推。运动员的名次决定了他们的获奖情况:

  • 名次第 1 的运动员获金牌 "Gold Medal" 。
  • 名次第 2 的运动员获银牌 "Silver Medal" 。
  • 名次第 3 的运动员获铜牌 "Bronze Medal" 。
  • 从名次第 4 到第 n 的运动员,只能获得他们的名次编号(即,名次第 x 的运动员获得编号 "x")。

使用长度为 n 的数组 answer 返回获奖,其中 answer[i] 是第 i 位运动员的获奖情况。

解:这道题的思路很简单,首先要得到名次,就需要排序。然后对照原数组,按照对应的位置给出排名情况。一开始写的是得到一个排完序的数组,然后两个for循环嵌套,一个个对照,结果放进answer数组,但是这样做会超出时间限制,时间复杂度为O(n^2),所以后面又用到了哈希表,这样就可以快速得到对应键值的在原数组的下标

1)这里为了巩固学习的新知识,排序采用了堆排序

a. 首先将原数组复制一份,再将复制的数组变成小根堆

b. 每次将堆顶元素和最后一个元素交换,再将堆数组的长度减1,把其余的部分再进行siftdown,变成小根堆后,重复交换操作和长度减1,以及siftdown操作,以此完成堆排序。

2)哈希表存好原数组以及对应的原始下标,将排完序的数组的值循环给哈希表,得到原始位置,将名次按照原始位置放入answer数组中即可。

代码:

//1.用堆排序,将数组排成降序
//2.将在ret数组中找到score数组中数据所在的下标名次就是i+1
//3.创建answer数组,将对比出来的结果依次放入answers数组class Solution {int[] ret;public void siftDown(int parent,int usedSize){int child = 2 * parent + 1;while(child < usedSize){//child是否需要换位置if(child + 1 < usedSize && ret[child] > ret[child+1]){child++;}if(ret[child] < ret[parent]){int temp;temp = ret[child];ret[child] = ret[parent];ret[parent] = temp;parent = child;child = 2 * parent + 1;}else{break;}}}public void heapSort(int end){while(end > 0){int temp;temp = ret[end];ret[end] = ret[0];ret[0] = temp;siftDown(0,end);end--;}}public String[] findRelativeRanks(int[] score) {//为防止超时(一开始使用两个for循环嵌套得answer数组超时了...),使用哈希表Map<Integer,Integer> scoreIndexMap = new HashMap<>();for(int i = 0;i < score.length;i++){scoreIndexMap.put(score[i],i);}String[] answer = new String[score.length]; ret = Arrays.copyOf(score,score.length);int child = ret.length-1;int parent = (child-1)/2;for(int i = parent ; i >= 0 ; i--){siftDown(i,ret.length);}//创建好小根堆后,使用堆排序(降序)heapSort(score.length-1);for(int i = 0;i < ret.length;i++){//找到对应位置int originalIndex = scoreIndexMap.get(ret[i]);if(i == 0){answer[originalIndex] = "Gold Medal";}else if(i == 1){answer[originalIndex] = "Silver Medal";}else if(i == 2){answer[originalIndex] = "Bronze Medal";}else{answer[originalIndex] = String.valueOf(i+1);}}return answer;}
}

3.两数之和

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target  的那 两个 整数,并返回它们的数组下标。

你可以假设每种输入只会对应一个答案,并且你不能使用两次相同的元素。

你可以按任意顺序返回答案。

解:这里一开始用的是暴力解法,两个循环嵌套遍历即可。降低时间复杂度可以使用哈希表,提供利用哈希表的解法。

1)遍历nums数组,将target - nums[ i ] 给哈希表,查看哈希表是否存在对应的数,如果咩有就将num[ i ] 和 i 放进哈希表,然后继续判断。

这里的巧妙就在于哈希表并没有一开始就放入数据,而是在遍历过程一步步将数据放入哈希表。

代码:

class Solution {public int[] twoSum(int[] nums, int target) {//为了降低时间复杂度,采用哈希表Map<Integer,Integer> hashtable =new HashMap<>();for(int i = 0;i<nums.length;i++){//在哈希表中查找是否存在target-nums[i],如果有就把位置返回if(hashtable.containsKey(target - nums[i])){return new int[]{hashtable.get(target-nums[i]),i};}hashtable.put(nums[i],i);}return new int[0];}
}

4.相同的树

给你两棵二叉树的根节点 p 和 q ,编写一个函数来检验这两棵树是否相同。

如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。

解:弄清true和false的情况,同时遍历两棵树即可。

1)true:

a. 两颗树都为null

b. 节点的值相同(如果节点的值相同,则可以进行下一步,而不是返回true,最终返回true还是要看节点是否同时到了null

2)false:

a. 一颗树为空,另一棵树不为空

b. 节点的值不相同

3)最后返回 左子树的比较情况&&右子树的比较情况

代码:

class Solution {public boolean isSameTree(TreeNode p, TreeNode q) {if (p == null && q == null) {return true;} else if (p == null || q == null) {return false;} else if (p.val != q.val) {return false;} else {return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);}}
}

5.对称二叉树

给你一个二叉树的根节点 root , 检查它是否轴对称。

解:关键在于找到判断轴对称的方法,代码应该怎么写。(和第4题差不多思想,直接看代码也可)

1)先判断root.left 和root.right 是否相等,相等则继续向下探查,直到出现null 或者二者数值不同时返回true或者false(如果root为null,则直接返回true)

2)再通过递归,root.left作为L,root.right作为R,判断L.left 和 R.right是否相等,以及L.right 和 R.left 是否相等

3)true和false的情况和第4题差不多,可以看代码理解,最后返回 judge(L.left,R.right) && judge(L.right,R.left)

代码:

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode() {}*     TreeNode(int val) { this.val = val; }*     TreeNode(int val, TreeNode left, TreeNode right) {*         this.val = val;*         this.left = left;*         this.right = right;*     }* }*/
class Solution {public boolean judge(TreeNode L,TreeNode R){if(L == null && R == null){return true;}else if(L != null && R == null || L == null && R != null){return false;}else if(L.val != R.val){return false;}//判断对称return judge(L.left,R.right) && judge(L.right,R.left);}public boolean isSymmetric(TreeNode root) {if(root == null){return true;}return judge(root.left,root.right);}
}

OK,就先这样

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

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

相关文章

UNet改进(15):分组注意力机制在UNet中的应用探索

引言 注意力机制已成为现代深度学习架构中不可或缺的组成部分,特别是在计算机视觉领域。近年来,各种注意力机制的变体被提出,以解决不同场景下的特定问题。本文将深入探讨一种称为分组注意力(Grouped Attention)的机制,以及它如何被集成到经典的UNet架构中,从而提升模型在…

C++之路:类基础、构造析构、拷贝构造函数

目录 前言从结构体到类类的声明与使用基础声明继承声明数据与函数声明与调用声明调用 类的访问修饰符类对象的内存分布类内数据相关静态变量非静态变量 类成员函数相关普通成员函数友元函数构造与析构函数构造函数析构函数 拷贝构造函数总结 前言 面向对象编程有三大特性&#…

黑神话悟空游戏舆情分析

完整项目包点击文末名片 黑神话悟空上线初期舆情分析 背景 《黑神话&#xff1a;悟空》在上线首日便创下了全球游戏行业的多项新纪录&#xff0c;包括Steam同时在线人数超过222万&#xff0c;全渠道总销量超过450万份&#xff0c;总销售额超过15亿元。本项目旨在对 3A 游戏《黑…

python的or-tools算法踩坑

debug模式代码好的,然后正常运行不行(用的PyCharm) 不知道为什么debug模式这个可以的,但是正常模式不行 用or-tools算路径的时候 因为要多次到达同一个点,但是or-tools不支持,所以弄了虚拟点和真实点的距离是0,但是实际上如果虚拟点到真实点为0的话or-tools结果秒出,但是实…

docker-compose一键部署全栈项目。springboot后端,react前端

部署总览前端打包: 我们将配置 package.json&#xff0c;使用 npm run build (内部调用 vite build) 来打包。这个过程将完全在 Docker 构建镜像的过程中自动完成&#xff0c;你的主机上甚至不需要安装 Node.js。后端打包: 我们将配置 pom.xml&#xff0c;使用 mvn clean packa…

MCMC:高维概率采样的“随机游走”艺术

MCMC&#xff08;马尔可夫链蒙特卡洛&#xff09; 是一种从复杂概率分布中高效采样的核心算法&#xff0c;它解决了传统采样方法在高维空间中的“维度灾难”问题。以下是其技术本质、关键算法及实践的深度解析&#xff1a; 本文由「大千AI助手」原创发布&#xff0c;专注用真话…

HarmonyOS免密认证方案 助力应用登录安全升级

6月21日&#xff0c;2025年华为开发者大会"安全与隐私分论坛"在松山湖顺利举办。本论坛聚焦App治理与监管、星盾安全2.0的核心能力等进行深度分享与探讨。其中&#xff0c;HarmonyOS Passkey免密认证方案作为安全技术创新成果备受瞩目。该方案基于FIDO协议实现&#…

flutter flutter_vlc_player播放视频设置循环播放失效、初始化后获取不到视频宽高

插件&#xff1a;flutter_vlc_player: ^7.4.3 问题1&#xff1a;设置循环播放_controller.setLooping(true);无用。 解决方法&#xff1a; //vlcPlayer设置循环播放失效&#xff0c;以这种方式失效循环播放 _setLoopListener() async {if (_videoController!.value.hasError…

React与Vue的主要区别

React和Vue都是当今最流行、最强大的前端Javascript框架&#xff0c;它们都能构建出色的单页面应用。 以下是React和Vue的主要区别&#xff1a; React&#xff1a; React官方自称是一个用于构建用户界面的JavaScript库&#xff08;尤其是UI组件&#xff09;。它专注于视图层。…

浏览器原生控件上传PDF导致hash值不同

用户要求对上传的pdf计算hash排重&#xff0c;上线后发现排重失败 1、postman直接调用接口没有发现问题&#xff0c;每次获取的hash值是一样的 2、apifox网页版&#xff0c;调用接口发现问题&#xff0c;清除缓存后&#xff08;将选择的文件删除重新选择&#xff09;&#xf…

.net 的依赖注入

依赖注入(Dependency Injection,简称 DI)是一种软件设计模式,旨在将对象之间的依赖关系从代码内部解耦出来,通过外部提供的方式来建立依赖关系,从而提高软件的可维护性、可测试性和可扩展性。以下从概念、工作原理、常见类型、在不同框架中的应用等方面进行详细解释: 概…

【unitrix】 4.17 类型级别右移运算实现解析(shr.rs)

一、源码 这段代码实现了类型级别的右移运算&#xff08;>>&#xff09;&#xff0c;包括对整数和定点数的支持。 /*类型级别的右移运算实现* 编制人: $ource* 修改版次:0版完成版* 本版次创建时间: 2025年6月27日* 最后修改时间: 2025年7月2日 Sub1修改* 待完善问题&a…

Java 并发核心:AQS(AbstractQueuedSynchronizer) 详解

一、什么是 AQS&#xff1f; AbstractQueuedSynchronizer&#xff08;简称 AQS&#xff09;是 Java 并发包 java.util.concurrent.locks 中的一个核心同步框架&#xff0c;用于构建锁和同步器&#xff0c;如&#xff1a; ReentrantLockReentrantReadWriteLockCountDownLatchS…

LoRA 实战指南:NLP 与 CV 场景的高效微调方法全解析

大模型已成 AI 应用的“标配”&#xff0c;但高昂的训练和部署成本让很多企业望而却步。LoRA&#xff08;Low-Rank Adaptation&#xff09;作为一种轻量级微调方案&#xff0c;正成为 NLP 与 CV 场景中低成本定制的利器。本文详细通过详细介绍 LoRA 的核心原理、在文本与图像任…

centos指令

一、python 1、查询运行中脚本 ps aux | grep python2、关闭脚本进程 kill -15 <PID> # 优雅终止&#xff08;SIGTERM&#xff09; kill -9 <PID> # 强制终止&#xff08;SIGKILL&#xff09;

用c语言写一个找两张图片不同处的游戏

回答 思考完成 我们计划开发一个用C语言实现的查找两张图片不同之处的游戏。这个程序需要加载两张图片&#xff0c;然后允许用户通过点击等方式标记出差异的位置。我们将使用一个简单的图形库&#xff08;例如SDL&#xff09;来处理图像和用户交互。步骤&#xff1a;1.加载两…

【深度学习:进阶篇】--4.3.seq2seq与Attention机制

学习目标 目标 掌握seq2seq模型特点掌握集束搜索方式掌握BLEU评估方法掌握Attention机制 应用 应用Keras实现seq2seq对日期格式的翻译 目录 学习目标 1.seq2seq 1.1.定义 1.2.条件语言模型理解 1.3.应用场景 2.注意力机制 2.1.长句子问题 2.2.定义 2.3.公式 3.机器…

MYSQL与PostgreSQL的差异

一、架构设计的根本差异 进程模型 vs 线程模型 ​PostgreSQL​&#xff1a;采用多进程架构&#xff08;每个连接独立进程&#xff09;&#xff0c;通过共享内存通信。优势在于进程隔离性强&#xff0c;单连接崩溃不影响整体服务&#xff0c;但资源消耗较高。 ​MySQL​&…

Wpf布局之StackPanel!

文章目录 前言一、引言二、使用步骤 前言 Wpf布局之StackPanel&#xff01; 一、引言 StackPanel面板在水平或垂直的堆栈中放置元素。这个布局容器通常用于更大、更复杂窗口中的一些区域。 二、使用步骤 StackPanel默认是垂直堆叠 <Grid><StackPanel><Butt…

【MySQL】 内置函数

目录 1.时间函数2.字符串函数3.数学函数4.其他函数 1.时间函数 函数名称描述current_date()当前日期current_time()当前时间current_timestamp()当前时间戳date(datetime)返回datetime参数的日期部分date_add(date,interval d_value_type)在date中添加日期/时间&#xff0c;in…