题目 找出数组中重复的数字. 在一个长度为 n 的数组 nums 里的所有数字都在 0-n-1 的范围内.数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次.请找出数组中任意一个重复的数字. 示例 1: 输入: [2, 3, 1, 0, 2, 5, 3] 输出:2 或 3 限制: 2 <= n <= 100000 思路一:哈希表 初始化哈希表大小为数组元素大小,初始值为-1(因为数组中所有元素大于0). 遍历数组每个数字n,如果哈希值为0,表示该数字已经存在,直接返回…
问题描述 找出数组中重复的数字. 在一个长度为 n 的数组 nums 里的所有数字都在 0-n-1 的范围内.数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次.请找出数组中任意一个重复的数字. 示例 1: 输入: [2, 3, 1, 0, 2, 5, 3] 输出:2 或 3 限制: 2 <= n <= 100000 这道题和leetcode 287. 寻找重复数相似: 代码1 时间复杂度\(O(N)\),空间复杂度\(O(N)\). class Solution {…
题目:找出数组中重复的数字. 说明:在一个长度为n的数组里的所有数字都在0~n-1的范围内,数组中某些数字是重复的,但是不知道有几个数字重复了,也不知道每个数字重复了几次.请找出数组中任意一个重复的数字.例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那个对应的输出是重复的数字2或3. 分析:关键点:长度为n的数组里的所有数字都在0~n-1的范围内.既然数字都在0-n-1,那么可以将数据放入下标中.若下标中已存在此数,则表明此数据重复.否则,交换numbers[i]    numbe…
题目一:找出数组中重复的数字.在一个长度为n的数组里的所有数字都在0~n-1的范围内.数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次.请找出数组中任意一个重复的数字.例如,如果输入长度为7的数组{2, 3, 1, 0, 2, 5, 3},那么对应的输出是重复的数字2或者3. 测试用例: 长度为n的数组里包含一个或多个重复的数字. 数组中不包含重复的数字. 无效输入测试用例(输入空指针:长度为n的数组中包含0~n-1之外的数字) 测试代码: void test(cha…
题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素.例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1. 解题思路: 1.暴力解法,从头到尾遍历一次,我们就能找出最小的元素,复杂度为O(n),但是没有利用输入的旋转数组的特性,肯定达不到面试官的要求. 2.二分查找,这里的数组可以看成两个有序的子数组,二分查找对有序数组非常有效,复杂度为O(logn). 具体分析: 1.先分析数组的特点…
题目:在一个长度为n的数组里的所有数字都在0到n-1的范围内.数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复的次数.请找出数组中任意一个重复的数字.例如如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是重复的数字2或者3. 为此题目提供三种想法,但是只实现书上的一种方法 1.先将数组排序,然后扫描数组就很容易得到重复的数字 2.利用HashSet,遍历数组,如果set中不存在数组中的值就直接放入set,否则就是重复数字 3.我们注意到数组中的数字都在0…
数组中重复的数:题目:找出数组中重复的数,题目描述:在一个长度为n的数组里的所有数字都在0到n-1的范围内.数组中某些数字是重复的,但不知道有几个数字是重复的.也不知道每个数字重复几次.请找出数组中任意一个重复的数字.例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是重复的数字2或者3. 分析: <一>首先进行重新排序然后从头进行扫描即可.1.比较下标,如果下标index等于数组num[index]继续比较下一个如果不等于:将index与num[index]比较:如果…
题目: 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. 1 2 8 9 2 4 9 12 4 7 10 13 6 8 11 15 思路:每次取右上角的一个数字(该例子中取9),如果9大于要找的数字则排除9的那列,否则派出9 的那行 public class Test3 { //arr为要查找数字的数组,num为要查找的数字 public static boolean find(…
题目:在一个长度为n+1的数组里的所有数字都在1~n的范围内,所以数组中至少有一个数字是重复的.请找出数组中任意一个重复的数字,但是不能修改输入的数组.例如,如果输入长度为8的数组{2,3,5,4,3,2,6,7},那么对应的输出是重复的数字2或者3. 方法1:利用辅助函数,逐一把原数组的每个数字复制到辅助数组.如果原数组中被复制的数字是m,则把它复制到辅助数组中下标为m的位置.如果下标为m的位置上已经有数字了,则说明该数字重复了.由于使用了辅助空间,故该方案的空间复杂度是O(n) public…
题目:请实现一个函数,把字符串中的每个空格替换成“%20”.例如输入“We are happy”,则输出”We%20are%20happy”. 原因:在网络编程中,如果URL参数中含有特殊字符,如:空格.“#”等,可能导致服务器端无法获得正确的参数值.我们需要将这些特殊符号转换成服务器识别的字符.转换规则是在“%”后面跟上ASCII码的两位十六进制的表示.比如:空格的ASCII码是32,即十六进制的0x20,因此空格被替换成“%20”. 时间复杂度为O(n2)不足以拿到Offer 现在我们考虑怎…
题目:输入某二叉树的前序遍历和中序遍历的结果,请重新构造出该二叉树.假设输入的前序遍历和中序遍历的结果中不包含重复的数字.例如输入的前序遍历序列为{1,2,4,7,3,5,6,8}和中序遍历为{4,7,2,1,5,3,6,8},则重建出二叉树并输出它的头结点. 前序遍历:根节点-->左节点-->右节点 中序遍历:左节点-->根节点-->右节点 后序遍历:左节点-->右节点-->根节点 在二叉树的前序遍历序列中,第一个数字总是树的根节点的值.但在中序遍历中,根节点的值在序…
问题描述 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数. 示例 1: 输入: [7,5,6,4] 输出: 5   限制: 0 <= 数组长度 <= 50000 这道题和leetcode 315.计算后面较小数字的个数一样. 代码 首先给一个超出时间限制的暴力解法: class Solution { public: int reversePairs(vector<int>& nums) { int…
题目描述: 输入一个链表,从尾到头打印链表每个节点的值.返回新链表. import java.util.Stack; //定义链表结构 class ListNode { int value; ListNode next; } public class PrintListReverse { public static void main(String[] args) { ListNode node1 = new ListNode(); ListNode node2 = new ListNode()…
题目:写一个函数,输入n,求斐波那契数列的第n项.斐波那契数列的定义如下: 1.效率很低效的解法,挑剔的面试官不会喜欢 使用递归实现: public class Fibonacci { public long getNum(int n){ if(n<=0){ return 0; }else if(n==1){ return 1; }else{ return getNum(n-1)+getNum(n-2); } } } 我们不难发现在这颗树中有很多的节点是重复的,而且重复的节点数会随着n的增大而急…
题目:用两个队列实现栈. 分析:通过一系列的栈的压入和弹出操作来分析用队列模拟一个栈的过程,如图所示,我们先往栈内压入一个元素a.由于两个队列现在都是空,我们可以选择把a插入两个队列中的任一个.我们不妨把a插入queue1.接下来继续往栈内压入b,c两个元素.我们把它们都插入queue1.这个时候 queue1包含3个元素a,b,c其中a位于队列的头部,c位于队列的尾部. 现在我们考虑从栈内弹出一个元素.根据栈的后进先出的原则,最后被压入栈的c应该最先被弹出.由于c位于queue1的尾部,而我们…
题目:用两个栈实现一个队列.队列的声明如下,请实现它的两个函数appendTail和deletedHead,分别完成在队列尾部插入节点和在队列头部删除节点的功能. 分析: 我们通过一个具体的例子来分析该队列插入和删除元素的过程.首先插入一个元素a,不妨先把它插入到stack1,此时stack1 中的元素有{a},stack2为空.再压入两个元素b和c,还是插入到stack1中,此时stack1中的元素有{a,b,c},其中c位于栈顶,而stack2仍然为空. 这个时候,我们试着从队列中删除一个元…
题目:给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回.注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针. 分析: 根据中序遍历的特点,要找到一个节点的下一个节点无非就是三种情况: 1.有右子树,这时只需要把其右孩子作为下一个遍历的(并不是要找的)节点,然后沿着该节点的左子树(如果有的话)出发,直到遇到叶子节点,那么该叶子节点就是其下一个要找的节点: 2.没有右子树,则判断该节点是否是其父节点的左孩子,如果是则其下一个要找的节点是其父节点: 3.如果不是其父节点…
问题描述 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字. 你可以假设数组是非空的,并且给定的数组总是存在多数元素. 示例 1: 输入: [1, 2, 3, 2, 2, 2, 5, 4, 2] 输出: 2 限制: 1 <= 数组长度 <= 50000 代码 时间复杂度\(O(N)\),空间复杂度\(O(N)\) class Solution { public: int majorityElement(vector<int>& nums) { map<in…
题目描述 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. 输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素. 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1. NOTE:给出的所有元素都大于0,若数组大小为0,请返回0. 题目分析 第一种方法:我们发现旋转数组在旋转后,有个分界点,而这个分界点就是最小的那个数. 第二种方法:分析第一种方法,我们发现时间复杂度为O(n),然而利用二分法的话,时间复杂度是可以做到O(logn)的,不…
(将BST改成排序的双向链表.) 我的方法一:根据BST的性质,如果我们中序遍历BST,将会得到一个从小到大排序的序列.如果我们将包含这些数字的节点连接起来,就形成了一个链表,形成双向链表也很简单.关键是我们要知道我们在准备连接一个节点时,我们要知道它之前处理的那个节点,也就是小于它的最大一个节点.如果用迭代的方法,这个信息是丢失的,所以我们要用一个变量保存这个节点.下面是中序遍历的迭代方法,处理的过程变成了连接,处理完后更新lasthandle. public TreeNode build(T…
(min函数的作用是返回栈内最小值) 首先这个栈要具有普通栈所具有的push()和pop()方法,那么内部一定包含一个Stack.至于还要能实现min函数,而且还是在O(1)时间复杂度内,我们不得不考虑用额外的空间. 如果直接使用一个int变量存储当前的最小值,我们的确可以获得最小值,但是当栈pop()了以后,我们无法获得次小值.我们需要一个数据结构来动态保存每个时刻的最小值,每当push()和pop()的时候,同样更新这个数据结构,而且时间复杂度也是O(1),那么看来需要额外O(n)的空间了.…
书中方法一:递归,这种方法效率不高,因为可能会有很多重复计算. public long calculate(int n){ if(n<=0){ return 0; } if(n == 1){ return 1; } return calculate(n-1) + calculate(n-2); } 书中方法二:更好的方法是将这个斐波那契数列的计算理解成动态规划,第n步的结果依赖于第n-1步和第n-2步的结果,状态转移方程很容易写出来. public long calculate2(int n){…
书中方法一:反转应该立刻想到栈,利用一个栈完成链表的反转打印,但是用了额外的O(n)空间. public void printFromTail(ListNode first){ Stack<ListNode> stack = new Stack<ListNode>(); while(first != null){ stack.push(first); first = first.next; } while(!stack.isEmpty()){ System.out.print(st…
[简单-剑指 Offer 53 - I. 在排序数组中查找数字 I] 统计一个数字在排序数组中出现的次数. 示例 1: 输入: nums = [5,7,7,8,8,10], target = 8 输出: 2 示例 2: 输入: nums = [5,7,7,8,8,10], target = 6 输出: 0 限制: 0 <= 数组长度 <= 50000 方法1:使用multiset数据结构的count函数,直接计算某个数字在数据结构中的个数 class Solution { public: mu…
剑指 Offer 53 - I. 在排序数组中查找数字 I Offer_53_1 题目描述 方法一:使用HashMap package com.walegarrett.offer; /** * @Author WaleGarrett * @Date 2021/2/9 20:10 */ import java.util.HashMap; import java.util.Map; /** * 题目描述:统计一个数字在排序数组中出现的次数. */ /** * 方法一:使用HashMap存储数字出现的…
题目 剑指 Offer 53 - I. 在排序数组中查找数字 I 思路1 一般来说,首先想到的是使用一个变量,从头开始遍历整个数组,记录target数组出现的次数,但是这样的时间复杂度是O(n),还是不够高效 题目说了,是排序数组,一想到排序数组,我们可以想到使用二分法: 找出第一个target所在的位置和最后一个target所在的位置,那么出现的次数就是end - start + 1了 代码 class Solution { public int search(int[] nums, int…
[简单-剑指 Offer 53 - II. 0-n-1中缺失的数字] 一个长度为n-1的递增排序数组中的所有数字都是唯一的,并且每个数字都在范围0-n-1之内.在范围0-n-1内的n个数字中有且只有一个数字不在该数组中,请找出这个数字. 示例 1: 输入: [0,1,3] 输出: 2 示例 2: 输入: [0,1,2,3,4,5,6,7,9] 输出: 8 限制: 1 <= 数组长度 <= 10000 方法1:遍历数组,在遍历的过程中比较数组下标与数值是否相同,不相同则输出下标即可. class…
剑指 Offer 53 - II. 0-n-1中缺失的数字 Offer_53 题目详情 java代码 package com.walegarrett.offer; /** * @Author WaleGarrett * @Date 2021/2/9 20:33 */ /** * 题目详情:一个长度为n-1的递增排序数组中的所有数字都是唯一的,并且每个数字都在范围0-n-1之内. * 在范围0-n-1内的n个数字中有且只有一个数字不在该数组中,请找出这个数字. */ public class Of…
题目 剑指 Offer 53 - II. 0-n-1中缺失的数字 思路1 排序数组找数字使用二分法 通过题目,我们可以得到一个规律: 如果数组的索引值和该位置的值相等,说明还未缺失数字 一旦不相等了,从左到右第一个不相等位置的索引值就是缺失的数字的值 所以我们使用二分法查找第一个索引值和数组的值不相等的位置,此时索引值就是我们要的结果了 如果没有缺失,就输出数组的长度 代码 class Solution { public int missingNumber(int[] nums) { int l…
说明: 1.本系列是根据<剑指Offer>这个系列做的一个小笔记. 2.直接动力是因为师兄师姐找工作很难,而且机械出生的我面试算法更难. 3.刚开始准备刷LeetCode.LintCode,突然看见一个大神博客,同为研究僧为啥差别那么大呢? 4.在别人基础之上进行部分优化,总结自己的观点. 问题: 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. 思路: 1.普通想法:行列循环…