剑指Offer刷题实录
本专栏记录了本人二刷剑指Offer的题解
SplendideMendax
通信小白
展开
-
剑指Offer第三十四题:第一个只出现一次的字符
剑指Offer第三十四题:第一个只出现一次的字符 思路1: 如果一个字符在字符串中第一次出现的位置与最后一次出现的位置相同,那么这个字符就只出现一次 求String中某个字符第一次出现的位置indexOf(char c) 求String中某个字符最后一次出现的位置lastIndexOf(char c) public class Solution { public int FirstNotRepeatingChar(String str) { if(str == null ||原创 2020-09-03 10:03:52 · 186 阅读 · 0 评论 -
剑指Offer第三十三题:丑数
.剑指Offer第三十三题:丑数 此题思路参考: /* 说下思路,如果p是丑数,那么p=2^x * 3^y * 5^z 那么只要赋予x,y,z不同的值就能得到不同的丑数。 如果要顺序找出丑数,要知道下面几个特(fei)点(hua)。 对于任何丑数p: (一)那么2*p,3*p,5*p都是丑数,并且2*p<3*p<5*p (二)如果p<q, 那么2*p<2*q,3*p<3*q,5*p<5*q 现在说说算法思想: 由于1是最小的丑数,那么从1开始,把2*1,3*1,原创 2020-09-03 09:38:01 · 225 阅读 · 0 评论 -
剑指Offer第三十二题:把数组排成最小的数
剑指Offer第三十二题:把数组排成最小的数 暴力思路:递归回溯得到所有的排列组合,取出值最小的排列 结题思路:对数组进行排序,排序结果能够按照组合数最小的顺序排列 关键怎么排序,这里使用局部比较的方式,当两个字符串s1和s2,组成的字符串s1+s2字典序小于s2+s1时,将s1放在s2的前边。 这样得到的数组就是想要的结果了,只需要将其串联为一个字符串就可以了 import java.util.*; public class Solution { public String PrintMinN原创 2020-09-03 09:08:05 · 138 阅读 · 0 评论 -
剑指Offer第三十一题:十进制整数1到n中1出现的总次数
剑指Offer第三十一题:十进制整数1到n中1出现的总次数 参考思路:牛客网网友:https://www.nowcoder.com/profile/7046624 public class Solution { public int NumberOf1Between1AndN_Solution(int n) { int count = 0; int i = 1; int high = 0,low = 0, curr = 0; whi原创 2020-09-02 23:38:44 · 147 阅读 · 0 评论 -
剑指Offer第三十题:连续子数组的最大和
剑指Offer第三十题:连续子数组的最大和 使用动态规划来求解 使用一个临时变量tempsum,返回值是sum 遍历整个数组,当tempsum>0时,tempsum加上下一个数组元素,当tempsum小于等于0时,tempsum = 下一个数组元素的值。 每遍历一个结点更新sum的值,取tempsum和sum 的较大值 最大值有两种来源,当前值或者前边的字段和加当前值 public class Solution { public int FindGreatestSumOfSubArray原创 2020-09-02 23:06:54 · 105 阅读 · 0 评论 -
剑指Offer第二十九题:最小的k个数
剑指Offer第二十九题:最小的k个数 使用一个最大堆:根结点最大 最大堆先存储数组中前k个元素,将数组中其余的元素逐一与最大堆顶元素比较,如果小于堆顶元素,就将堆顶元素移除,并添加当前元素。 实现: 使用PriorityQueue来实现最大堆,内置比较器(Integer o1,Integer o2){当o1<o2时,返回-1,否则返回1,可以实现队头元素大于队尾元素,PriorityQueue的底层是用最大堆或者最小堆实现的} import java.util.*; public原创 2020-09-02 22:48:48 · 130 阅读 · 0 评论 -
剑指Offer第二十八题:数组中出现次数超过一半的数
剑指Offer第二十八题:数组中出现次数超过一半的数 如果这个数存在,那么将数组排序后,中位数必然是这个数 所以只需要将数组排序,取中位数,再检查中位数的个数是否超过半数 import java.util.*; public class Solution { public int MoreThanHalfNum_Solution(int [] array) { if(array == null || array.length == 0){ return 0;原创 2020-09-02 18:47:08 · 77 阅读 · 0 评论 -
剑指Offer第二十七题:字符串的排列
剑指Offer第二十七题:字符串的排列 典型的递归回溯: 当前排列 标志列表(已选为true,未选为false) 临时字符,避免重复 递归终止条件:当前排列长度等于总长度curr.length() == strchar.length 递归回溯:将下一个一个false并且与前一次字符不相同的字符加入当前排列,递归,结束后回溯 为了避免重复,要求在一开始对字符进行排序,这样重复的字符在连续位置,只需要比较前后元素就可以避免掉重复元素。 import java.util.*; public class原创 2020-09-02 18:35:17 · 111 阅读 · 0 评论 -
剑指Offer第二十五题:深拷贝复杂链表
剑指Offer第二十五题:深拷贝复杂链表 输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针random指向一个随机节点),请对此链表进行深拷贝,并返回拷贝后的头结点。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空) 这个题的难点在于每一个新链表结点要连接到对应的新链表中的两个指针指向的结点 很难在建表过程中也把连接关系建立起来 可以使用hashmap,键指向原结点,值指向新结点 再把链表遍历一遍,利用hashmap的对应关系,建立连接关系 /*原创 2020-09-02 11:57:23 · 179 阅读 · 0 评论 -
剑指Offer第二十四题:二叉树中和为某一给定值的路径
剑指Offer第二十四题:二叉树中和为某一给定值的路径 典型的递归回溯 当当前结点是叶子结点并且路径和为target时,找到一条路径 当当前和currSum大于target时,这个结点往下不需要再找了 当当前结点不是叶子结点并且currSum小于target时,查找该结点的左右子节点 import java.util.ArrayList; /** public class TreeNode { int val = 0; TreeNode left = null; TreeNod原创 2020-09-02 11:32:11 · 117 阅读 · 0 评论 -
剑指Offer第二十三题:由一个后序遍历判断是否是二叉搜索树
剑指Offer第二十三题:由一个后序遍历判断是否是二叉搜索树 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则返回true,否则返回false。假设输入的数组的任意两个数字都互不相同。 这个题要从二叉搜索树的定义来做,左子树全部小于根节点,右子树全部大于根节点,方案就是检查每一层的左子树和右子树是否都能满足大小关系 现在问题就是怎么找出左子树和右子树,这个根据后序遍历的特点,左子树在前,右子树在中间、根结点在最后边 从左往右找,如果发现一个结点的值大于根节点的值,说明到原创 2020-09-02 11:01:00 · 329 阅读 · 0 评论 -
剑指Offer第二十二题:层序遍历二叉树
剑指Offer第二十二题:层序遍历二叉树 层序遍历需要使用一个队列来保存每一层每一个结点,当队列中一个结点出队时,将其左右子结点入队。 import java.util.*; /** public class TreeNode { int val = 0; TreeNode left = null; TreeNode right = null; public TreeNode(int val) { this.val = val; } } */原创 2020-09-02 10:38:58 · 150 阅读 · 0 评论 -
剑指Offer第二十一题:栈的压入、弹出序列
剑指Offer第二十一题:栈的压入、弹出序列 这个题思路就是创建一个栈来模拟压栈和出栈的操作 将压栈数组逐个压栈,使用一个索引来记录当前出栈序列的位置,当出现栈顶元素和出栈数组当前数相等时,说明需要出栈操作,进行出栈,因为可能在一次压栈之后会有多个出栈,因为要用while循环来出栈 import java.util.*; public class Solution { public boolean IsPopOrder(int [] pushA,int [] popA) {原创 2020-09-02 09:50:40 · 108 阅读 · 0 评论 -
剑指offer第二十题:包含min函数的栈
剑指offer第二十题:包含min函数的栈 定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数(时间复杂度应为O(1))。 import java.util.Stack; public class Solution { Stack<Integer> stack = new Stack<>(); Stack<Integer> minStack = new Stack<>(); public void push(原创 2020-08-18 09:27:54 · 82 阅读 · 0 评论 -
剑指Offer第十九题:顺时针打印矩阵
剑指Offer第十九题:顺时针打印矩阵 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下4 X 4矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10. 用这个边界top、left、right、bottom来限制循环的范围,每遍历一圈,更新四个边界值 import java.util.ArrayList; public class Solution原创 2020-08-18 09:27:38 · 109 阅读 · 0 评论 -
剑指Offer第十八题:二叉树的镜像
剑指Offer第十八题:二叉树的镜像 递归,当前结点不是叶子结点也不是null时,直接交换该结点的左右子树,然后递归 /** public class TreeNode { int val = 0; TreeNode left = null; TreeNode right = null; public TreeNode(int val) { this.val = val; } } */ public class Solution { p原创 2020-08-18 09:27:06 · 103 阅读 · 0 评论 -
剑指Offer第十七题;树的子结构,检查一个树是否为另一个树的子树
剑指Offer第十七题;树的子结构,检查一个树是否为另一个树的子树 输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构) 外递归函数: 进行条件判断,当两个树都不为空时,才有可能是子结构 当找到一个结点和子结构的根结点相同时,进入内递归函数检查其结点是否相同 内递归函数: 当子树为空时,说明已经遍历了子树的所有结点,并且全部相同,返回true 当父树为空时,能进入这个if说明子树还不是null,因此不是子结构,返回false 当子树结点和父树结点相等时,正常递归检查原创 2020-08-17 21:35:30 · 88 阅读 · 0 评论 -
剑指Offer第十六题:合并两个排序的链表
剑指Offer第十六题:合并两个排序的链表 题目描述 输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。 思路:使用归并排序 初始化: 创建一个dummyNode,来作为头结点的前一个结点 创建一个currNode = dummyNode,来遍历链表 为了防止破坏原链表,用两个临时指针p1和p2指向list1和list2 遍历链表,将两个链表中当前头结点较小的结点归并到链表中 /* public class ListNode { int val;原创 2020-08-17 20:57:21 · 121 阅读 · 0 评论 -
剑指Offer第十五题:反转链表
剑指Offer第十五题:反转链表 输入一个链表,反转链表后,输出新链表的表头。 头插法 初始化: 头结点pre = new ListNode(head); 临时结点next,指向head的下一个结点 遍历链表,循环停止条件next == null 2.1 先让head指向next结点 head = next 2.2 先用临时结点存储下一个结点next = next.next 2.3 进行反转,修改head.next,让head指向pre: head.next = pre; 2.4 更新pr原创 2020-08-17 20:41:22 · 96 阅读 · 0 评论 -
剑指Offer第十四题:打印链表中倒数第k个结点
剑指Offer第十四题:打印链表中倒数第k个结点 输入一个链表,输出该链表中倒数第k个结点。 使用快慢指针法 快指针先走k步,然后快慢指针同时走,当快指针到尾巴时,慢指针指向倒数第k个元素 /* public class ListNode { int val; ListNode next = null; ListNode(int val) { this.val = val; } }*/ public class Solution { public原创 2020-08-17 18:39:16 · 184 阅读 · 0 评论 -
剑指Offer第十三题:调制数组顺序使奇数位于偶数的前边,并且奇数相对顺序不变,偶数相对顺序不变
剑指Offer第十三题:调制数组顺序使奇数位于偶数的前边 并且奇数相对顺序不变,偶数相对顺序不变 输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。 要保持相对顺序,就需要采用一种稳定的排序算法,如冒泡排序算法 冒泡排序法: 1.确定排序遍历的轮数:array.length次,i 从0到length-1 2.每一轮的逻辑:当相邻元素前偶后奇时,交换;在每一轮开始前,后i个元素已经排好了顺原创 2020-08-17 18:20:11 · 244 阅读 · 0 评论 -
剑指Offer第十二题:数值的整数次方
剑指Offer第十二题:数值的整数次方 给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。保证base和exponent不同时为0 这道题没什么算法需要考虑,只需要考虑几种情况就好 1、底数或者指数为0时 2、指数是正数数时 3、指数是负数时 public class Solution { public double Power(double base, int exponent) { if(base == 0.0){原创 2020-08-17 17:05:28 · 82 阅读 · 0 评论 -
剑指Offer第十一题:二进制中1的个数
剑指Offer第十一题:二进制中1的个数 输入一个整数,输出该数32位二进制表示中1的个数。其中负数用补码表示。 常规算法:获得这个数的二进制字符串,对字符串诸位计数 public int NumberOf1(int n) { String s = Integer.toBinaryString(n); int count = 0; for(int i = 0; i<s.length(); i++){ if(s.charAt(i)原创 2020-08-17 16:53:37 · 125 阅读 · 0 评论 -
剑指Offer第十题:矩形覆盖
剑指Offer第十题:矩形覆盖 我们可以用21的小矩形横着或者竖着去覆盖更大的矩形。请问用n个21的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法? 根据第一个矩形是横着还是竖着分为两种 递归 public class Solution { public int RectCover(int target) { if(target <= 0){ return 0; } if(target == 1){原创 2020-08-17 16:24:12 · 91 阅读 · 0 评论 -
剑指Offer第九题:变态跳台阶
剑指Offer第九题:变态跳台阶 一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。 第一步可以跳1,2,3,4,。。。,n步 //f(n) = f(n-1) + f(n-2) + f(n-3)+f(n-4)+。。。+f(0) //f(n-1) = f(n-2) + f(n-3)+f(n-4)+。。。+f(0) //f(n) = 2*f(n-1); //递归 递归 public class Solution { public int Ju原创 2020-08-17 16:05:59 · 94 阅读 · 0 评论 -
剑指Offer第八题:跳台阶
一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。 斐波那契数列 同样可以使用两种做法 递归 public class Solution { public int JumpFloor(int target) { if(target == 1){ return 1; } if(target == 2){ return 2; .原创 2020-08-17 14:25:19 · 79 阅读 · 0 评论 -
剑指Offer第七题:斐波那契数列
剑指Offer第七题:斐波那契数列 递归,性能较差 public class Solution { public int Fibonacci(int n) { if( n == 0) return 0; if( n == 1){ return 1; } else{ return Fibonacci( n-1 )+ Fibonacci( n-2 );原创 2020-08-16 22:16:31 · 84 阅读 · 0 评论 -
剑指Offer第六题:旋转数组的最小数字
剑指Offer第六题:旋转数组的最小数字 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。 NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。 采用二分法,比较的基准是索引为0的元素, 第一步:将尾部可能存在与array[0]相同的元素剔除 第二步:检查数组是否发生了旋转,若无,直接返回array[0] 第三步:二分搜索,当mid原创 2020-08-16 18:00:48 · 112 阅读 · 0 评论 -
剑指Offer第五题:用两个栈实现队列
剑指Offer第五题:用两个栈实现队列 用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。 栈1主要用来入队,直接入栈即可 栈2主要用来出队,出队时,如果栈2不为空,就将栈1元素全部压入栈2,再将栈2栈顶元素弹栈,这样可以确保弹栈元素是最早入队的 import java.util.Stack; public class Solution { Stack<Integer> stack1 = new Stack<Integer>();原创 2020-08-16 17:29:32 · 107 阅读 · 0 评论 -
剑指Offer第四题:重建二叉树
剑指Offer第四题:重建二叉树 == 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。== ** 重建二叉树,需要使用递归,起始找到根节点,创建根节点,再递归查找根节点的左右子树 ** /** * Definition for binary tree * public class TreeNode { *原创 2020-08-16 17:18:29 · 132 阅读 · 0 评论 -
剑指Offer第三题:从尾到头打印链表
剑指Offer第三题:从尾到头打印链表 == 输入一个链表,按链表从尾到头的顺序返回一个ArrayList。 == /** * public class ListNode { * int val; * ListNode next = null; * * ListNode(int val) { * this.val = val; * } * } * */ import java.util.ArrayList; impo原创 2020-08-16 16:45:18 · 78 阅读 · 0 评论 -
剑指Offer第二题:替换空格
剑指Offer第二题:替换空格 请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。 public class Solution { public String replaceSpace(StringBuffer str) { //将字符串变成StringBuffer, //创建一个StringBuffer,从头到位逐个检查str,遇见一个空格就append("原创 2020-08-16 16:37:09 · 95 阅读 · 0 评论 -
剑指Offer第一题:二叉数组中的查找
二叉数组的查找 public class Solution { public boolean Find(int target, int [][] array) { //数组是右下最大,左上最小 //查找时应该从右上查找,如果有target大于当前数,则说明当前行已经失效,应将行号加1 //如果小于当前数,则应加列号减1 if(array == null || array.length == 0 || array[0]原创 2020-08-16 16:28:54 · 72 阅读 · 0 评论