刷题篇
DU777DU
本人是西安科技大学准毕业生,目前还是一个新手,请大家多多指教
展开
-
删除链表中的节点,存在重复元素
删除链表中的节点描述:请编写一个函数,使其可以删除某个链表中给定的(非末尾)节点。传入函数的唯一参数为要被删除的节点。思路:没有头结点,所以无法通过前驱指向后继来删除,转化为删除node后继节点的方式,不改变地址只改变值(1)把node后继的值赋给node(2)把node后继设为node.next = node.next.next代码:class Solution { public void deleteNode(ListNode node) { n..原创 2021-08-23 12:12:17 · 145 阅读 · 0 评论 -
剑指40最小的k个数,回文数
最小的k个数描述:输入整数数组arr,找出其中最小的k个数。例如,输入4、5、1、6、2、7、3、8这8个数字,则最小的4个数字是1、2、3、4。思路:topK问题,最小k个数:维护一个容量为k的大堆(1)特殊值处理(2)创建一个堆(优先级队列PriorityQueue),默认是小堆,所以要重写比较器,lambda表达式((v1,v2) -> v2-v1)(3)循环遍历数组,判断若堆未满就直接入队,或者当前值小于堆顶元素,堆顶出队,然后该值入队,循环完毕后堆里就是k个最小...原创 2021-08-23 11:13:45 · 164 阅读 · 1 评论 -
反转字符串,局部反转链表
反转字符串描述:编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 char[] 的形式给出。不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。你可以假设数组中的所有字符都是 ASCII 码表中的可打印字符思路:给定的是字符数组,特殊判断,若s为空,或长度小于2,直接返回(1)双指针指向首尾元素left,right(2)若l<r,就交换两个元素,然后都往中间移,l++,r--(3)直到l=r,只剩中间一个元原创 2021-08-22 18:43:50 · 197 阅读 · 1 评论 -
将有序数组转化为二叉搜索树,剑指54二叉搜索树的第k大节点
将有序数组转化为二叉搜索树描述:给你一个整数数组 nums ,其中元素已经按 升序 排列,请你将其转换为一棵 高度平衡 二叉搜索树。高度平衡 二叉树是一棵满足「每个节点的左右两个子树的高度差的绝对值不超过 1 」的二叉树。思路:递归中写一个方法(1)利用中序遍历保证稳定性,若l>r,代表没有节点,返回null(为什么不是l>=r , 若r在l后一位,递归返回到这一层执行右边,l+1=r直接返回不能打印这个节点)(2)找到中间节点作为根节点,递归左右子树,返回root原创 2021-08-22 12:23:12 · 121 阅读 · 1 评论 -
剑指61扑克牌中的顺子,合并两个有序数组
扑克牌中的顺子描述:从扑克牌中随机抽5张牌,判断是不是一个顺子,即这5张牌是不是连续的。2~10为数字本身,A为1,J为11,Q为12,K为13,而大、小王为 0 ,可以看成任意数字。A 不能视为 14。思路:若为5连顺子,5张牌一不能重复,2是最大牌-最小牌<5(1)考虑不能重复,使用HashSet(2)定义最大牌为0,最小牌14(0~13)(3)遍历数组,若值为0,是joker跳过continue若值大于max,赋给max若值小于min,赋给min判断set中是否包原创 2021-08-22 11:12:57 · 142 阅读 · 0 评论 -
剑指58翻转单词顺序,整数反转
翻转单词顺序描述:输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。为简单起见,标点符号和普通字母一样处理。例如输入字符串"I am a student. ",则输出"student. a am I"。思路:(1)先把边上的空格都去掉,string.trim()方法(2)定义一个字符串数组StringBuilder来接收返回的字符串数组(3)定义两个指针都指向字符串尾部(4)循环开始找完整的单词,为了防止数组越界,循环总是在i>=0的情况下进行循环进行判断,若原创 2021-08-21 18:12:09 · 138 阅读 · 0 评论 -
杨辉三角,剑指21调整数组把奇数放在偶数前面
1. 杨辉三角描述:思路:主要是用list集合(1)先判断numRows为空的情况,若为空直接返回null(2)第一行只有一个1,用list.add(1),在放到ret第一个中(ret里存的都是ArrayList)(3)从第二行开始,循环定义当前行curRow是一个list集合,当前行第列的数总是1,从第二列开始到倒数第二列,循环定义上一行prevRow=ret.get(i-1),把上一行的当前列和前一列得数相加,得到的结果就是当前行curRow的当前列的数,再把最后一列curRow.a原创 2021-08-19 12:20:00 · 271 阅读 · 1 评论 -
连续子数组的最大和(两种方法)
连续子数组的最大和描述:输入一个整型数组,数组中的一个或连续多个整数组成一个子数组。求所有子数组的和的最大值。思路1:一维动规特殊情况处理:数组长度为0,返回0,数组长度为1,返回1动规4步:(1)确定状态:最后一步,dp[i]代表以元素nums[i] 为结尾的连续子数组最大和(2)转移方程:若dp[i-1]>0,说明之前的结果会让子数组更大F[i]=F[i-1]+nums[i],否则不会更大就不加了F[i]=nums[i],定义变量max保存每一轮结果的最大值(因为nums[i]原创 2021-08-18 23:59:41 · 2093 阅读 · 1 评论 -
剑指10斐波那契数列,青蛙跳台阶
斐波那契数列描述:写一个函数,输入n,求斐波那契(Fibonacci)数列的第n项(即F(N))。思路:动规4步(1)确定状态:最后一步,对于第n的数来说,就是前两个数之和(2)转移方程:从2开始每个数都是前两个数之和F[n]=F[n-1] + F[n-2](3)初始条件:0个数就是0,1是1(0和1没有前两个数)(4)计算顺序:每一步用前一步的值,所以从前往后代码:class Solution { public int fib(int n) { ...原创 2021-08-18 22:18:48 · 124 阅读 · 0 评论 -
剑指27二叉树的镜像,剑指26树的子结构
二叉树的镜像描述:请完成一个函数,输入一个二叉树,该函数输出它的镜像思路:递归:(1)若根节点为空直接返回(2)先把左孩子节点保存到tmp(防止右孩子节点覆盖左孩子节点后没有左孩子节点了)(3)递归调用该方法,参数填右孩子,返回值赋给左孩子(4)递归调用该方法,参数填tmp,返回值赋给右孩子(5)每层递归完毕后返回当前层根节点代码:class Solution { public TreeNode mirrorTree(TreeNode root) {原创 2021-08-17 23:53:49 · 86 阅读 · 0 评论 -
剑指18删除链表的节点,剑指22链表中倒数第k个节点
删除链表的节点描述:给定单向链表的头指针和一个要删除的节点的值,定义一个函数删除该节点。返回删除后的链表的头节点。思路:(1)若头结点的值就等于删除值,返回头结点下一个节点即可(2)删除需要前驱结点辅助,定义cur指向头结点下一个,prev指向头结点(3)循环进行判断若cur不为空并且cur的值也不是删除值的时候,双指针分别向后移,前驱先动(4)while结束,两种情况,若cur不为空则是找到删除节点了,前驱节点的后继直接指向cue的后继(5)无论是cur为空了还是删除了,链表的原创 2021-08-17 21:13:06 · 68 阅读 · 0 评论 -
在排序数组中查找数字1(2种方法),0~n-1中缺失的数字(2种方法)
在排序数组中查找数字1描述:统计一个数字在排序数组中出现的次数。思路:利用哈希表,key为元素值(和target比较),value为出现次数(1)初始化一个HashMap(2)循环遍历数组,判断若map中存在Key为nums[i],则put(nums[i], map.get(nums[i]) + 1)否则put键为num[i],值为1(3)判断map中若没有ket为target,返回0(4)返回map中以target为键的值就是出现次数代码:class Solution原创 2021-08-12 19:12:39 · 1098 阅读 · 1 评论 -
从尾到头打印链表,左旋转字符串,包含min函数的栈
从尾到头打印链表描述:输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。思路:输入正向输出反向符合栈的特性(1)定义一个栈保存节点,循环把所有节点入栈(2)定义一个数组,长度就是栈长,依次把栈顶元素放进数组就好了(3)返回数组代码:class Solution { public int[] reversePrint(ListNode head) { Stack<ListNode> s = new Stack<&g原创 2021-08-12 16:43:07 · 86 阅读 · 0 评论 -
数组中重复的数字,替换空格
剑指offer03数组中重复的数字描述:找出数组中重复的数字。在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。思路:找重复的值用Set集合很好(1)定义出一个HashSet(2)遍历数组,若set包含当前i的值就返回i,否则把i放入set(3)循环结束若还没有返回就是没有,返回-1代码:class Solution { p原创 2021-08-12 00:37:43 · 188 阅读 · 1 评论 -
初见LeetCode:两数之和
思路:采用哈希表的方法(1)定义一个 HashMap<Integer, Integer>,key为元素的值(因为nums[i] + nums[j] = target),val为下标(2)遍历数组,遍历到i时判断若哈希表包含key为target - nums[i],则此时两key相加的值就是target,而val就是下标,返回两个下标即可,否则就把当前i位置的元素值作key存入哈希表中(3)循环结束也没返回代表没找到,返回null代码:class Solution {原创 2021-08-08 23:02:38 · 115 阅读 · 3 评论 -
字符串中的第一个唯一字符(两种思路:1 用系统给的HashMap,2 自己定义哈希表)
描述:给定一个字符串,找到它的第一个不重复的字符,并返回它的索引。如果不存在,则返回 -1。思路1:用系统给的HashMap思路:(1) 定义一个HashMap<Character, Integer>,键为字符,值为出现次数(2)循环遍历字符串,取出i下标的字符,判断若该键的值为空,值改为1,否则改为值+1,循环完毕后map存的就是所有字符以及出现次数(3)再次循环遍历字符串,判断若下标为i的键值为1,改下标对应的就是第一次出现的唯一字符,返回i,若循环完毕还没有返回值..原创 2021-08-07 21:35:35 · 181 阅读 · 1 评论 -
复制带随机指针的链表(结合HashMap与链表)图解详细
描述:给你一个长度为 n 的链表,每个节点包含一个额外增加的随机指针 random ,该指针可以指向链表中的任何节点或空节点。构造这个链表的深拷贝。深拷贝应该正好由 n 个 全新 节点组成,其中每个新节点的值都设为其对应的原节点的值。新节点的 next 指针和 random 指针也都应指向复制链表中的新节点,并使原链表和复制链表中的这些指针能够表示相同的链表状态。复制链表中的指针都不应指向原链表中的节点 。例如,如果原链表中有 X 和 Y 两个节点,其中 X.random --> Y ..原创 2021-08-07 21:35:05 · 144 阅读 · 0 评论 -
只出现一次的数据(三种不同思路解法)
描述:给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素1. 使用异或机制思路:思路1:异或(1)先定义异或的值single= 0(0和任意数字异或都是数字本身)(2)for-each循环遍历数组,得到每一个元素都和single异或,利用异或的交换律,先异或所有出现两次的数据,single还是0(3)最后和出现一次的数据异或,此时single的结果就是那个数据,返回single代码:class Solution {原创 2021-08-07 10:43:41 · 567 阅读 · 0 评论 -
迭代方法遍历二叉树
1. 前序遍历思路:迭代方法(使用栈):(1)定义一个list集合ret保存返回值(2)若root为空,直接返回ret(3)初始化一个栈,把root赋给cur来遍历二叉树(4)循环判断若cur不为空代表有节点,入栈,并添加到集合list中,“根左右”的根完成cur后移到左孩子节点,直到cur为空代表无左孩子,“根左右”的左完成(5)此时栈顶就是左孩子的父节点,弹出栈顶赋给top,在让cur后移到右孩子节点,明显也得循环,此时用一个外层循环顺便包裹之前的循环,条件为cur不为空并且栈不为空(原创 2021-08-06 10:40:49 · 1049 阅读 · 1 评论 -
(前序与中序)/(中序与后序)遍历序列构造二叉树
1.前序与中序遍历序列构造二叉树描述:给定一棵树的前序遍历preorder与中序遍历inorder。请构造二叉树并返回其根节点思路:根据前序遍历找根(1)定义成员变量preIndex来遍历前序遍历数组定义一个辅助方法buildTreeChild来构建树,参数为(前序遍历数组,中序遍历数组,中序遍历开始下标,中序遍历结束下标),返回值为树的根,若中序遍历开始下标>中序遍历结束下标,代表没有数组区间(没有左子树或者右子树),返回null(2)从前序遍历数组中获取根节点,...原创 2021-08-06 10:40:30 · 248 阅读 · 2 评论 -
根据二叉树创建字符串,二叉树的最近公共祖先,二叉搜索树与双向链表
1. 根据二叉树创建字符串描述:你需要采用前序遍历的方式,将一个二叉树转换成一个由括号和整数组成的字符串。空节点则用一对空括号 "()" 表示。而且你需要省略所有不影响字符串与原始二叉树之间的一对一映射关系的空括号对思路:先序遍历的思想(1)方法参数为当前根节点和字符串(2)若根为空,直接返回,否则把根的值传入字符串(3)若左孩子为空,两种情况,若右孩子也为空,直接返回,否则是无左有右,字符串传入()(4)若左孩子不为空,字符串传入(,递归调用该方法,归的过程字符串传入),整个递原创 2021-08-06 10:40:17 · 74 阅读 · 0 评论 -
对称二叉树,二叉树层序遍历,构造二叉树
1. 对称二叉树描述:给定一个二叉树,检查它是否是镜像对称的。思路:(1)定义一个辅助方法isSymmetricChild,返回左孩子和右孩子是否对称(2)若root为空,认为对称返回true(3)方法isSymmetricChild,若左右子树都为空,返回true若左右子树一个为空或值不同都返回false(4)若当前左右子树都不空且值相同,递归左子树的左孩子和右子树的右孩子(对称),递归左子树的右孩子和右子树的左孩子(对称),都为true则返回true(5)返回 isSym原创 2021-08-05 10:26:59 · 175 阅读 · 2 评论 -
平衡二叉树从顶到底和从底到顶
1. 平衡二叉树描述:给定一个二叉树,判断它是否是高度平衡的二叉树。本题中,一棵高度平衡二叉树定义为:一个二叉树每个节点的左右两个子树的高度差的绝对值不超过 1 。1.1 从顶到底思路:从顶到底,O(N^2),基础(1)定义辅助方法depth求得当前树的高度(2)若root为空,是平衡的,返回true(3)求左子树和右子树的高度(4)若左子树和右子树高度差的绝对值不超过1(利用Math.abs()求绝对值)并且左右子树都平衡(递归),返回true代码:c.原创 2021-08-04 09:21:36 · 219 阅读 · 1 评论 -
二叉树的最大深度,相同的树,另一棵树的子树
1.二叉树的最大深度描述:给定一个二叉树,找出其最大深度。二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。说明:叶子节点是指没有子节点的节点。思路:(1)递归调用左子树和右子树(2)若根为空返回0(3)返回左右子树中大的那一个+1(根本身)代码:class Solution { public int maxDepth(TreeNode root) { if(root == null) return 0; i.原创 2021-08-04 09:21:17 · 269 阅读 · 0 评论 -
二叉树的一点简单基本操作
1. 二叉树所有节点1.1遍历思路:使用前中后任意一个遍历方式遍历二叉树,每次递归都执行一次size++代码: static int size = 0; void getSize1(Node root){ if(root == null) return; size++; getSize1(root.left); getSize1(root.right); }1.2子问题思...原创 2021-08-04 09:20:38 · 80 阅读 · 0 评论 -
递归方法遍历完全二叉树
1. 前序遍历描述:打印顺序为: 根左右思路:考虑使用递归的方法(1)先定义一个List类型的变量ret来保存返回值(2)定义一个方法来进行递归操作(传入当前的根节点和res),若根为空return。因为是根左右的方式,所以先把root的值存到res.add里,然后再递归左孩子和右孩子(3)递归完成后返回res即可class Solution { public List<Integer> preorderTraversal(TreeNode root)原创 2021-08-04 09:20:57 · 228 阅读 · 0 评论 -
队列和栈的相互转换
1. 用队列实现栈描述:请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push、top、pop 和 empty)。实现 MyStack 类:void push(int x) 将元素 x 压入栈顶。int pop() 移除并返回栈顶元素。int top() 返回栈顶元素。boolean empty() 如果栈是空的,返回 true ;否则,返回 false 。注意:1. 你只能使用队列的基本操作 —— 也就是push to back、p..原创 2021-08-03 10:03:07 · 294 阅读 · 0 评论 -
设计最小栈,有效的括号
描述:设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。push(x) —— 将元素 x 推入栈中。pop()—— 删除栈顶的元素。top()—— 获取栈顶元素。getMin() —— 检索栈中的最小元素。思路:(1)定义两个栈,一个普通栈,一个最小栈(2)入栈push方法,给普通栈放元素时,直接放。给最小栈放元素时需要判断,若为空直接放,若不为空时,判断若最小栈中的值<=val时才放(3)出栈pop方法,判断栈若为空(两个栈同时为..原创 2021-08-03 10:04:49 · 76 阅读 · 0 评论 -
设计循环队列
描述:设计你的循环队列实现。 循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队首之后以形成一个循环。它也被称为“环形缓冲器”。循环队列的一个好处是我们可以利用这个队列之前用过的空间。在一个普通队列里,一旦一个队列满了,我们就不能插入下一个元素,即使在队列前面仍有空间。但是使用循环队列,我们能使用这些空间去存储新的值。你的实现应该支持如下操作:MyCircularQueue(k): 构造器,设置队列长度为 k 。Front: 从队首获取元素。如果队列为原创 2021-08-03 10:02:25 · 146 阅读 · 0 评论 -
链表中的倒数第k个节点,回文链表
1. 链表中的倒数第k个节点描述:输入一个链表,输出该链表中倒数第k个结点。思路:(1)先进行合法性判断,若k<0 || head == null ,此时不合法,直接return null;(2)定义一组快慢指针先指向head,先让fast走k-1步,实现为循环让fast在fast.next不为空的情况下(为空就是最后一个了)向后走一位并让k--,直到k-1==0)),若fast.next==null时仍有k-1!=0则说明k过大非法(3),使得slow在fast前k-1位(倒原创 2021-08-01 12:46:07 · 126 阅读 · 1 评论 -
相交链表,环形链表2,移除链表元素
1. 相交链表描述:给你两个单链表的头节点headA和headB,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回null。思路:(1)先定义两个指针a,b分别指向两个链表头部(考虑空指针异常,头结点都应不为空,为空的话定无交点,直接返回null)(2)考虑若两链表长度相等则同时走相等长度必回遇到,若不相等则构造出相等(a+b=b+a)(3)循环直到a=b判断:a若不为null就一直在A往后走==null时再从B走,b若不为null就一直在B往后走==n...原创 2021-08-01 11:19:15 · 148 阅读 · 0 评论 -
合并两个有序链表,链表的中间节点,删除链表中的重复元素
1. 合并两个有序链表描述:将两个升序链表合并为一个新的升序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。思路:(1)先定义一个傀儡指针ListNode perHead = new ListNode(-1),再定义前驱结点prev也指向perHead(2)循环判断若l1.val<l2.val,说明l1是头结点,prev.next=l1,else是l2,循环一次就让prev确定一个节点prev = prev.next(3)哪个链表先空,prev就在哪个链表的尾结点...原创 2021-08-01 12:34:48 · 1115 阅读 · 0 评论