数据结构与算法
陆离2333
这个作者很懒,什么都没留下…
展开
-
剑指 Offer 57. 和为s的两个数字
题目输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们的和正好是s。如果有多对数字的和等于s,则输出任意一对即可。代码双指针碰撞法初始化: 双指针 ii , jj 分别指向数组 numsnums 的左右两端 (俗称对撞双指针)。循环搜索: 当双指针相遇时跳出;计算和 s = nums[i] + nums[j]s=nums[i]+nums[j] ;若 s > targets>target ,则指针 jj 向左移动,即执行 j = j - 1j=j−1 ;若 s <原创 2021-07-01 20:25:46 · 72 阅读 · 0 评论 -
剑指 Offer 53 - II. 0~n-1中缺失的数字
题目一个长度为n-1的递增排序数组中的所有数字都是唯一的,并且每个数字都在范围0~n-1之内。在范围0~n-1内的n个数字中有且只有一个数字不在该数组中,请找出这个数字。思路思路1 直接法直接法就是直接遍历整个数组,找到第一个值和下标不同的位置,返回该下标即可。时间复杂度为O(n).class Solution { public int missingNumber(int[] nums) { int n=nums.length; for(int i=0;i原创 2021-06-26 20:37:43 · 56 阅读 · 0 评论 -
剑指 Offer 53 - I. 在排序数组中查找数字 I
题目统计一个数字在排序数组中出现的次数。思路一开始我想的是,直接for循环遍历,后面觉得,这题肯定不简单。于是我就去看了一下大佬们都是怎么写的。大佬们的思路就是用了二分搜索算法,求出右边界,然后一剪即可,可以说非常惊艳了。代码class Solution { public int bound(int[] nums,int t){ int mid=0,left=0,right=nums.length-1; while(left<=right){原创 2021-06-26 19:59:47 · 82 阅读 · 0 评论 -
剑指 Offer 52. 两个链表的第一个公共节点
题目输入两个链表,找出它们的第一个公共节点。思路典型的数据结构的链表题。解法非常经典。我感觉leetcode给的题解比我在王道数据结构上看的要简单清晰明了很多,也优雅很多。大体思路就是,设置两个指针a和b,分别从头开始遍历两个链表ha和hb,直到两指针相遇为止a==b。如果a遍历完了链表ha,则从链表hb开始遍历,指针b同理。最后返回a即可。代码/** * Definition for singly-linked list. * public class ListNode { *原创 2021-06-26 19:26:11 · 102 阅读 · 0 评论 -
76. 最小覆盖子串
题目:给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 “” 。注意:如果 s 中存在这样的子串,我们保证它是唯一的答案。示例 1:输入:s = “ADOBECODEBANC”, t = “ABC”输出:“BANC”示例 2:输入:s = “a”, t = “a”输出:“a”提示:1 <= s.length, t.length <= 105s 和 t 由英文字母组成进阶:你能设计一原创 2021-06-17 22:47:35 · 123 阅读 · 1 评论 -
剑指 Offer 39. 数组中出现次数超过一半的数字
题目数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。你可以假设数组是非空的,并且给定的数组总是存在多数元素。示例 1:输入: [1, 2, 3, 2, 2, 2, 5, 4, 2]输出: 2限制:1 <= 数组长度 <= 50000思路这道题有三种思路我想到了前两种。。。。第一种也是最简单的一种,就是对数组进行排序,然后中点元素就是多数元素。第二种更直接,但相对来说复杂一些,就是统计每个元素出现的次数,然后再判断即可。重点讲一下第三种方法,摩尔投票法,也是原创 2021-06-09 20:34:26 · 70 阅读 · 0 评论 -
剑指 Offer 42. 连续子数组的最大和
题目输入一个整型数组,数组中的一个或连续多个整数组成一个子数组。求所有子数组的和的最大值。要求时间复杂度为O(n)。示例1:输入: nums = [-2,1,-3,4,-1,2,1,-5,4]输出: 6解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。提示:1 <= arr.length <= 10^5-100 <= arr[i] <= 100思路我觉得这道题真的真的是非常难的题目了。一开始我想的是用穷举的方法,后面发现,时间复杂度太高了。然后看了题原创 2021-06-09 19:43:18 · 109 阅读 · 0 评论 -
剑指 Offer 30. 包含min函数的栈
题目定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的 min 函数在该栈中,调用 min、push 及 pop 的时间复杂度都是 O(1)。思路这道题其实还是有点难的,因为一开始我想的是用一个数组来存储。但是每次求最小元素就要遍历整个数组,时间复杂度为O(n)。不符合题意。因此考虑设置一个辅助栈来实现,辅助栈用于存放最小的元素。思路如下:push函数:1.将x压入栈a中2.如果栈b为空或者x小于等于栈b的栈顶元素,则将x压入栈b中;pop函数:1.如果a的栈顶元素等于b的栈原创 2021-06-09 19:07:43 · 80 阅读 · 0 评论 -
剑指 Offer 40. 最小的k个数
题目输入整数数组 arr ,找出其中最小的 k 个数。例如,输入4、5、1、6、2、7、3、8这8个数字,则最小的4个数字是1、2、3、4。示例 1:输入:arr = [3,2,1], k = 2输出:[1,2] 或者 [2,1]示例 2:输入:arr = [0,1,2,1], k = 1输出:[0]限制:0 <= k <= arr.length <= 100000 <= arr[i] <= 10000思路这道题非常简单,只需要排个序,然后输出前k个数即原创 2021-06-08 19:11:17 · 106 阅读 · 3 评论 -
剑指 Offer 24. 反转链表
题目定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。示例:输入: 1->2->3->4->5->NULL输出: 5->4->3->2->1->NULL限制:0 <= 节点个数 <= 5000思路反转链表最经典的办法莫过于头插法了。但需要注意的是浅拷贝和深拷贝的区别。对于基本数据类型而言,a=b,是直接将值复制一份,但对于引用数据类型而言,则是浅拷贝,即是对对象地址的复制,两者指向的仍是同一个对原创 2021-06-08 18:20:32 · 72 阅读 · 0 评论 -
剑指 Offer 17. 打印从1到最大的n位数
题目输入数字 n,按顺序打印出从 1 到最大的 n 位十进制数。比如输入 3,则打印出 1、2、3 一直到最大的 3 位数 999。示例 1:输入: n = 1输出: [1,2,3,4,5,6,7,8,9]说明:用返回一个整数列表来代替打印n 为正整数思路第一种思路,通过递归来完成第二种思路,直接调用Math类中的pow方法来完成代码class Solution { public int theMax(int n){ if(n==1) return 9;原创 2021-06-08 16:10:08 · 59 阅读 · 0 评论 -
剑指 Offer 22. 链表中倒数第k个节点
题目思路这道题还是特别简单的,就是设置两个指针,front和rear,让front指针先走k步,然后再让rear和front一起前进,直到front走到链表尽头为止。这是一道特别特别特别简单的数据结构题,我用脚趾头都能写出来。然而然而然而我却被测试例子各种吊打,一番总结之后,发现了其中有一个特殊情况要提前判断:就是就是就是要想判断链表长度和k之间的关系,如果链表长度小于k,那就说明倒数的节点就是头节点!!!代码/** * Definition for singly-linked l原创 2021-05-31 11:46:49 · 47 阅读 · 0 评论 -
剑指 Offer 29. 顺时针打印矩阵
题目思路写在前面,我觉得这道题放在easy难度就是离谱,一开始,我根本就写不出来,然后看了一下大神们的题解,有一位大神用了模拟有限状态机的方法来写,思路挺好的,但是大可不必,于是我简化了其中的思路,但其本质还是从一个状态转换到另一个状态。定义四个变量,top,right,bottom和left状态1:行不变,列变top++状态2:列不变,行变right–状态3:列变,行不变bottom–状态4:行变,列不变left++然后循环这四个状态,直到top>bottom和left&g原创 2021-05-31 11:10:14 · 76 阅读 · 0 评论 -
剑指 Offer 28. 对称的二叉树
题目思路重点是理解整个的递归思路。二叉树的题目的关键就在于递归。以本题为例,判断二叉树是否镜像相等,自顶而下递归考虑。代码/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */class Soluti原创 2021-05-27 20:50:00 · 40 阅读 · 0 评论 -
剑指 Offer 27. 二叉树的镜像
题目思路非递归:利用队列。根节点先入队。循环入队,条件:队列不为空(注意,LinkedList没有isEmpty()这个方法,判断队列不为空list.size()!=0)弹出队首节点。加入节点的左右孩子节点进队列中。交换左右孩子。递归:root.left = mirrorTree(root.right);root.right = mirrorTree(temp);非常简单,就是一个递归交换左右孩子节点,因为二叉树本身就是递归定义的。class Solution {原创 2021-05-27 20:02:17 · 67 阅读 · 0 评论 -
剑指 Offer 25. 合并两个排序的链表
题目输入两个递增排序的链表,合并这两个链表并使新链表中的节点仍然是递增排序的。示例1:输入:1->2->4, 1->3->4输出:1->1->2->3->4->4限制:0 <= 链表长度 <= 1000思路说实话,这道题还是特别简单的,只是第一次用java来写数据结构的题目,有一点点不顺手,比如说在本题中,我一直没有想清楚头节点的表示方法,因为题目给的listNode封装里边就没有头节点这一个概念。所以这种情况下,我们使用到原创 2021-05-26 21:20:05 · 66 阅读 · 0 评论 -
剑指 Offer 15. 二进制中1的个数
题目请实现一个函数,输入一个整数(以二进制串形式),输出该数二进制表示中 1 的个数。例如,把 9 表示成二进制是 1001,有 2 位是 1。因此,如果输入 9,则该函数输出 2。示例 1:输入:00000000000000000000000000001011输出:3解释:输入的二进制串 00000000000000000000000000001011 中,共有三位为 ‘1’。示例 2:输入:00000000000000000000000010000000输出:1解释:输入的二进制串 0原创 2021-05-26 20:33:50 · 102 阅读 · 2 评论 -
剑指 Offer 03. 数组中重复的数字
题目找出数组中重复的数字。在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。示例 1:输入:[2, 3, 1, 0, 2, 5, 3]输出:2 或 3来源:力扣(LeetCode)链接:https://leetcode-cn.com/problems/shu-zu-zhong-zhong-fu-de-shu-zi-lcof著作权归领扣网络所有。商业转载请联原创 2021-05-24 20:51:56 · 63 阅读 · 0 评论 -
剑指 Offer 09. 用两个栈实现队列
题目用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead ,分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素,deleteHead 操作返回 -1 )示例 1:输入:[“CQueue”,“appendTail”,“deleteHead”,“deleteHead”][[],[3],[],[]]输出:[null,null,3,-1]示例 2:输入:[“CQueue”,“deleteHead”,“appendTail”,原创 2021-05-24 20:19:43 · 56 阅读 · 0 评论 -
csp202012_2期末预测之最佳阈值
题目题目就略了,相信大家肯定也知道题目才过来看的,懒得贴题目了。思路先讲讲思路,思路有两种,第一种暴力解法,相信大家都会,但如果用这种解法的话,只有70分。第二种解法,是我在考场上没有想到的,现在才慢慢想清楚。如果按照题目的意思,写了一个predict函数,那一定会有双重循环,一定会超时。因此我们要降低时间复杂度,把O(n^2)降成O(n)。其实我们可以发现,双重循环的计算过程中存在重复计算,所以我们只需计算它有多少个0和多少个1.遍历思路:遍历0的话,从头开始遍历,等于前面的0数+1;遍历原创 2021-03-31 19:00:47 · 144 阅读 · 0 评论 -
csp201709_2公共钥匙盒
题目题解其实这道题还是有点难的。。。。难点我觉得主要有两个:1.能够想到将一组输入转换为取出和归还两个操作,从而建立出一个操作队列(这么想来,是不是应该用队列来做更好一点?)2.能够理清楚操作序列中的三级排列顺序,从而写出比较函数这里重点讲一下。首先我们阅读题目,然后理清楚操作序列的先后逻辑序列即可。先还号码小的钥匙,先进行还操作后进行取操作,先进行时间早的操作,再进行时间晚的操作,理请楚这个逻辑后,我们就可以写cmp函数了。bool cmp(KEY a,KEY b)//三级排序,先还小的,原创 2020-12-07 16:45:35 · 138 阅读 · 0 评论 -
csp201712_1最小差值
题目题解这道题还是比较简单的。一开始我想复杂了,我想求差值,那就两两求差值,然后再找出最小值。但后面我发现这个作法复杂了,还有更简单的做法。我们观察数据可以知道,差值最小肯定是存在于两个相邻的数之间。因此我们第一步,先将数据升序排序,然后遍历它,两两求其差值即可。代码#include <iostream>#include <algorithm>using namespace std;int main(){ int n; cin>>原创 2020-12-06 11:58:24 · 107 阅读 · 0 评论 -
csp201803_2碰撞的小球
题目题解我觉得这道题还是蛮多坑的,我来一个一个的讲一下我踩过的那些坑。解题思路其实这道题的解题思路还是比较简单的,创建一个ball类型的结构体数组,其属性有position,direction和num。我们可以规定direction为1,则是向右,-1则是向左。输入数据时,我就遇到了第一个坑。坑1一开始我的写法是:for(int i=0;i<n;i++){ cin>>b[i].position;}这个写法在codeblocks上运行是可以的,但是在csp提交平台原创 2020-12-06 11:34:59 · 169 阅读 · 0 评论 -
csp201809_2买菜
题目题解暴力解法这道题看似不知所云,比如说我看这道题,看了一堆,最后告诉我,要求他们的聊天的时间?!!!!what?????但是,当你在草稿纸上画个时间轴的图之后,一切问题都迎刃而解了。我们在时间轴上可以看出,这道题本质上就是在求一个共同区间的问题(根据我刷题经验,一般涉及时间段的问题都可以投影到时间轴上进行求解,有点类似于把时间问题转换面积问题)因此,一个暴力解法在我的脑海里浮现出来。先创建一个结构体,里边有两个元素,flagh和flagw,假如在某个时间点里,他们经过了,则置相应的标记为原创 2020-12-03 20:04:31 · 115 阅读 · 0 评论 -
csp201912_2回收站选址
题目题解这道题我也没有什么好的方法,说一下里边的坑吧,测试点无法满分通过,可能就是踩到里边的坑了。1.存储x和y应该用long long类型。其实这个坑我也有点不太明白,因为题目中说x,y<=109,然后int的范围是-231-231-1,应该是可以满足存储需求的,但是就是不能满分通过,我也无语。2.题目说1<=n<=103,一开始我本来是打算用vector来做的,后面看n不是很大,就打算直接建个[1010]的数组的来做,后面发现不能满分通过,把数组改大一点,就可以了。继续原创 2020-11-28 20:04:18 · 113 阅读 · 0 评论 -
csp202006-2稀疏向量
题目输入输出格式样例题解这道题乍一看下去很简单,不就是一个稀疏向量的存储加计算问题么,简单。然后现实就交会了我做人。。。。。。。。一开始写的时候,我发现了题目给的n我没有用上,但我不以为意,直接两重for循环,暴力解题。然后就是报运行超时的错误。。。。。。(哭泣)因为4到10组测试数据均是10的5次方起步,两重for循环的话,它的时间复杂度就是O(n^2),要想时间不超时,就必须的把时间复杂度降到O(n).此时我想的是牺牲空间要时间的暴力解法,设了两个特别大的整形数组去存稀疏向量。原创 2020-11-27 21:06:24 · 312 阅读 · 0 评论 -
csp202009-2风险人群筛查
题目样例题解其实这道题非常简单,我在本机上运行了好几组测试数据,包括样例数据还有自己造的数据,都感觉没有什么问题,但是一提交就错,而且是0分。这种情况下,应该先思考是不是输入输出的格式问题,因为oj系统与本机运行测试是不太一样的。但是我一开始没有想到这些,还以为是我代码的逻辑问题,de了一小时bug还是没有找到什么问题,但我更坚定的肯定不是代码逻辑的问题。兜兜转转,我才想到了输入上。一开始我设置的输入是逐个数据逐个数据输入,但这样好像不行。后面我改了一下,改成了两个数据一起输入,代码就满分通原创 2020-11-26 20:35:59 · 529 阅读 · 1 评论 -
csp202009-1检测点问题
题目运行结果其实从运行结果可以看出,一开始我是没有得满分的。按照csp往常套路来讲,样例能够运行通过,而最终却没有得满分,多半是因为最后的一个测试数据过大所导致的问题,但我回过头去检查了一波,感觉它最大就存200个数,怎么也不会超,但我又嫌麻烦,懒得去编200个数据来测一下看是哪里的问题,所以只能盯着代码找问题,终于被我找到了。。。。。原来是一开始我作死,怕麻烦,结构体数组我直接从1开始计数,导致我后面用sort函数时,习惯性还是传了数组名进去,因此出了问题。改法有两种:1.sort(cp+1原创 2020-11-26 17:12:15 · 555 阅读 · 0 评论 -
PAT乙级题库1015题德才论问题
德才论问题原题:输入样例:14 60 8010000001 64 9010000002 90 6010000011 85 8010000003 85 8010000004 80 8510000005 82 7710000006 83 7610000007 90 7810000008 75 7910000009 59 9010000010 88 4510000012 80 10010000013 90 9910000014 66 60输出样例:1210000013原创 2020-10-31 10:44:42 · 256 阅读 · 0 评论 -
C++解决进制转换问题(除基取余法)
题目描述:输入两个非负的十进制数A和B,输出A+B的D进制数。输入格式:在一行输入三个整数A,B和D。输出格式:输出A+B的D进制数。思路:我们首先要计算出A+B的值,然后再用除基取余法进行进制转换。除基取余法:设置一个数组ans[]用来存放D进制的每一位,然后用sum进行除于D进行取余操作,余数存在数组ans中。最后再将ans从高位往低位输出即可。代码实现:#include <iostream>using namespace std;int main(){int原创 2020-10-20 16:18:24 · 739 阅读 · 0 评论 -
一元多项式求导问题
题目:思路:我们第一个要考虑的问题就是如何存储该多项式。一元多项式由指数和系数构成,而指数通常是按照递减的顺序输入的,即我们通常在写一元多项式时也是按从高到低的次序写的。所以我们可以考虑用一个数组来存放系数即可。即a[e]=k,其中,k为系数,e为指数。我们要考虑的第二个问题是如何求导。按照我们平时的习惯,我们是从高次项往低次项求导。但是在此问题中,我们需要从低次项至高次项进行枚举,通过求导公式计算数组a的元素,即其实我们只需要计算系数即可,同时我们还要计算不为零的导数项个数。最后,我们要从高次原创 2020-10-18 17:12:14 · 848 阅读 · 0 评论 -
交通规划问题(最短路径树)
问题描述G国国王来中国参观后,被中国的高速铁路深深的震撼,决定为自己的国家也建设一个高速铁路系统。 建设高速铁路投入非常大,为了节约建设成本,G国国王决定不新建铁路,而是将已有的铁路改造成高速铁路。现在,请你为G国国王提供一个方案,将现有的一部分铁路改造成高速铁路,使得任何两个城市间都可以通过高速铁路到达,而且从所有城市乘坐高速铁路到首都的最短路程和原来一样长。请你告诉G国国王在这些条件下最少要改造多长的铁路。输入形式输入的第一行包含两个整数n, m,分别表示G国城市的数量和城市间铁路的数量。所有原创 2020-05-10 09:17:58 · 1327 阅读 · 0 评论 -
最优灌溉问题 (最小生成树Prim算法) C++实现
最优灌溉问题 C++问题描述输入形式输出形式样例输入和输出问题分析完整代码如下问题描述雷雷承包了很多片麦田,为了灌溉这些麦田,雷雷在第一个麦田挖了一口很深的水井,所有的麦田都从这口井来引水灌溉。 为了灌溉,雷雷需要建立一些水渠,以连接水井和麦田,雷雷也可以利用部分麦田作为“中转站”,利用水渠连接不同的麦田,这样只要一片麦田能被灌溉,则与其连接的麦田也能被灌溉。 现在雷雷知道哪些麦田之间可以建设水渠和建设每个水渠所需要的费用(注意不是所有麦田之间都可以建立水渠)。请问灌溉所有麦田最少需要多少费用来原创 2020-05-08 20:53:41 · 1425 阅读 · 0 评论