剑指Offer
lijieling123
努力赚钱
展开
-
图的最小生成树与最短路径
两者没有太大的关联,只不过在一定程度上应用了贪心算法的思想而已,但区别比较明显。一、区别最小生成树能够保证首先是树(对于n个顶点的图只有n-1条边),其次保证任意两个顶点之间都可达,再次保证这棵树的边权值之和为最小,但不能保证任意两点之间是最短路径。最短路径保证从源点S到目地点D的路径最小(有向图中不要求终点能到起点),不保证任意两个顶点都可达二、最小生成树普里姆(Prim)算法Prim算法是以某顶点为起点,逐步找各顶点上最小权值的边来构建最小生成树的算法描述:从单一顶点开始,普里姆算法原创 2022-04-09 11:35:16 · 1229 阅读 · 1 评论 -
剑指offer题目列表
后续把每一题做完的链接附在后面week1找出数组中重复的数字不修改数组找出数组中重复的数字二维数组中的查找替换空格从尾到头打印链表重建二叉树二叉树的下一个节点用两个栈实现队列斐波那契数列旋转数组最小的数字矩阵中的路径week2机器人的运动范围剪绳子二进制中1的个数数值的整数次方在O(1)时间删除链表节点删除链表中重复的节点正则表达式匹配表示数值的字符串调整数组顺序使奇数位于偶数前面链表中倒数第k个节点链表中环的入口节点week3反转链表合并两个排序的链表原创 2021-06-21 19:34:14 · 119 阅读 · 0 评论 -
剑指Offer题目思路整理(一)
二叉搜索树的后序遍历序列输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则返回true,否则返回false。假设输入的数组的任意两个数字都互不相同。样例输入:[4, 8, 6, 12, 16, 14, 10]输出:true思路:(后序遍历,递归) O(n)后序遍历,数组的最后一个值是二叉树的根节点,所以前面的值一部分小于根节点,一部分大于根节点,因为是二叉搜索树,找到比根节点小的,则为左子树,比根节点大的为右子树,然后递归整个数组即可。参考链接.原创 2021-05-08 16:09:23 · 76 阅读 · 0 评论 -
二进制中1的个数
输入一个3位整数,输出该数二进制表示中1的个数。注意:负数在计算机中用其绝对值的补码来表示。样例1输入:9输出:2解释:9的二进制表示是1001,一共有2个1。样例2输入:-2输出:31解释:-2在计算机里会被表示成11111111111111111111111111111110, 一共有31个1。解题思路1:(比较简单的) 式子n&=(n-1)同理为n=n&(n-1) &表示“与”,例如n=10110 ,则n-1=...原创 2021-04-21 17:05:44 · 194 阅读 · 0 评论 -
从尾到头打印链表
输入一个链表的头结点,按照从尾到头的顺序返回节点的值。返回的结果用数组存储。样例输入:[2, 3, 5]返回:[5, 3, 2]解题思路从前往后遍历一遍链表,再逆序C++/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * ..原创 2021-04-18 11:06:44 · 70 阅读 · 1 评论 -
构建乘积数组
给定一个数组A[0, 1, …, n-1],请构建一个数组B[0, 1, …, n-1],其中B中的元素B[i]=A[0]×A[1]×… ×A[i-1]×A[i+1]×…×A[n-1]。不能使用除法。样例输入:[1, 2, 3, 4, 5]输出:[120, 60, 40, 30, 24]思考题:能不能只使用常数空间?(除了输出的数组之外)解题思路动态规划 参考链接:https://www.acwing.com/solution/content/759/用两个数组left原创 2021-04-15 11:34:29 · 73 阅读 · 0 评论 -
不用加减乘除做加法
写一个函数,求两个整数之和,要求在函数体内不得使用+、-、×、÷四则运算符号。样例输入:num1 = 1 , num2 = 2输出:3解题思路二进制a+b=(a^b)+(a&b)其中a^b代表不进位的和,a&b代表进位class Solution {public: int add(int num1, int num2){ while(num2){ int sum=num1^num2; ..原创 2021-04-14 17:05:12 · 60 阅读 · 0 评论 -
求1+2+…+n
求1+2+…+n,要求不能使用乘除法、for、while、if、else、switch、case 等关键字及条件判断语句(A?B:C)。样例输入:10输出:55解题思路1.递归,用&代替if2.用开辟数组的方法class Solution {public: int getSum(int n) { int res=n; n>0&&(res+=getSum(n-1)); return r...原创 2021-04-14 16:54:05 · 146 阅读 · 0 评论 -
扑克牌的顺子
从扑克牌中随机抽5张牌,判断是不是一个顺子,即这55张牌是不是连续的。2∼10 为数字本身,A为1,J为11,QQ为12,KK为13,大小王可以看做任意数字。为了方便,大小王均以0来表示,并且假设这副牌中大小王均有两张。样例1输入:[8,9,10,11,12]输出:true样例2输入:[0,8,9,11,12]输出:true解题思路:先排序 排除0 判断是否有连续的数 除0之外的第一个数与最后一个数的差小于等于4class S...原创 2021-04-14 15:26:43 · 241 阅读 · 0 评论 -
圆圈中最后剩下的数字
0,1,…,n−10,1,…,n−1这nn个数字(n>0)(n>0)排成一个圆圈,从数字00开始每次从这个圆圈里删除第mm个数字。求出这个圆圈里剩下的最后一个数字。样例输入:n=5 , m=3输出:3解题思路采用递归f(n,m)=(f(n-1,m)+m) %nclass Solution {public: int lastRemaining(int n, int m){ if(n==1) return 0; ...原创 2021-04-14 16:02:05 · 117 阅读 · 0 评论 -
股票的最大利润
假设把某股票的价格按照时间先后顺序存储在数组中,请问买卖一次该股票可能获得的利润是多少?例如一只股票在某些时间节点的价格为[9,11,8,5,7,12,16,14]。如果我们能在价格为5的时候买入并在价格为161时卖出,则能收获最大的利润11。样例输入:[9, 11, 8, 5, 7, 12, 16, 14]输出:11先土土地暴力算法class Solution {public: int maxDiff(vector<int>& n...原创 2021-04-14 16:27:11 · 76 阅读 · 0 评论 -
骰子的点数
将一个骰子投掷n次,获得的总点数为s,s的可能范围为 n∼6n。掷出某一点数,可能有多种掷法,例如投掷22次,掷出3点,共有[1,2],[2,1]两种掷法。请求出投掷n次,掷出n∼6n 点分别有多少种掷法。样例1输入:n=1输出:[1, 1, 1, 1, 1, 1]解释:投掷1次,可能出现的点数为1-6,共计6种。每种点数都只有1种掷法。所以输出[1, 1, 1, 1, 1, 1]。样例2输入:n=2输出:[1, 2, 3, 4, 5, 6,...原创 2021-04-13 18:54:24 · 1158 阅读 · 0 评论 -
滑动窗口的最大值
给定一个数组和滑动窗口的大小,请找出所有滑动窗口里的最大值。例如,如果输入数组[2,3,4,2,6,2,5,1]及滑动窗口的大小3,那么一共存在6个滑动窗口,它们的最大值分别为[4,4,6,6,6,5]。注意:数据保证k大于0,且k小于等于数组长度。样例输入:[2, 3, 4, 2, 6, 2, 5, 1] , k=3输出: [4, 4, 6, 6, 6, 5]解题思路维护一个双向单调队列,队列放的是元素的下标。我们假设该双端队列的队头是整个队列的最大元素...原创 2021-04-13 17:06:12 · 232 阅读 · 2 评论 -
左旋转字符串
字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如输入字符串"abcdefg"和数字2,该函数将返回左旋转22位得到的结果"cdefgab"。注意:数据保证n小于等于输入字符串的长度。样例输入:"abcdefg" , n=2输出:"cdefgab"解题思路先把整个字符串翻转 对n分割的前后两部分再分别翻转class Solution {public: string leftRotateS...原创 2021-04-11 17:14:36 · 103 阅读 · 0 评论 -
翻转单词顺序
输入一个英文句子,单词之间用一个空格隔开,且句首和句尾没有多余空格。翻转句子中单词的顺序,但单词内字符的顺序不变。为简单起见,标点符号和普通字母一样处理。例如输入字符串"I am a student.",则输出"student. a am I"。样例输入:"I am a student."输出:"student. a am I"解题思路(开辟数组会额外浪费空间,采用下列方法)1.字符全部翻转2.具体到每个单词再翻转一次class Solution {pub.原创 2021-04-11 16:56:42 · 66 阅读 · 0 评论 -
和为S的连续正数序列
输入一个正数S,打印出所有和为S的连续正数序列(至少含有两个数)。例如输入15,由于1+2+3+4+5=4+5+6=7+8=15,所以结果打印出33个连续序列1∼5、4∼6 和7∼8。样例输入:15输出:[[1,2,3,4,5],[4,5,6],[7,8]]解题思路采用双指针,时间复杂度O(N)class Solution {public: vector<vector<int>> findContinuousSequence...原创 2021-04-11 15:57:02 · 58 阅读 · 0 评论 -
和为S的两个数字
输入一个数组和一个数字ss,在数组中查找两个数,使得它们的和正好是ss。如果有多对数字的和等于ss,输出任意一对即可。你可以认为每组输入中都至少含有一组满足条件的输出。样例输入:[1,2,3,4] , sum=7输出:[3,4]解题思路:采用hashclass Solution {public: vector<int> findNumbersWithSum(vector<int>& nums, int target) { ...原创 2021-04-11 15:20:43 · 57 阅读 · 0 评论 -
数组中唯一只出现一次的数字
在一个数组中除了一个数字只出现一次之外,其他数字都出现了三次。请找出那个只出现一次的数字。你可以假设满足条件的数字一定存在。思考题:如果要求只使用O(n)O(n)的时间和额外O(1)O(1)的空间,该怎么做呢?样例输入:[1,1,1,2,2,2,3,4,4,4]输出:3解题思路:状态机:初始状态(0,0)和1进行运算(0,0)-(1,0)-(0,1)-(0,0)和0进行运算,回到自身 int findNumberAppearingOnce...原创 2021-04-10 20:27:25 · 241 阅读 · 0 评论 -
数组中只出现一次的两个数字
一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。你可以假设这两个数字一定存在。样例输入:[1,2,3,3,4,4]输出:[1,2]解题思路异或得到 x^y 取 x与y中第k位为1的数 将数分为两个集合,第k位为1的集合和第k位不是1的集合 其中x y分别在这两个集合,且相同的元素是在同一个集合里面 (比如3,3,4,4也都在同一个集合) vector<int> findNumsAppearOnce(vect原创 2021-04-10 19:29:11 · 105 阅读 · 0 评论