算法学习
changtingwai58
这个作者很懒,什么都没留下…
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
碰撞的蚂蚁
题目描述在n个顶点的多边形上有n只蚂蚁,这些蚂蚁同时开始沿着多边形的边爬行,请求出这些蚂蚁相撞的概率。(这里的相撞是指存在任意两只蚂蚁会相撞) 给定一个int n(3<=n<=10000),代表n边形和n只蚂蚁,请返回一个double,为相撞的概率。思路:每个蚂蚁爬行的方向都有两个,即围绕多边形顺时针爬和逆时针爬,因此n个蚂蚁爬行的方法有2^n种。 只有当所有的蚂蚁按照同一个方向爬行才能保证所有原创 2016-08-07 00:05:44 · 464 阅读 · 0 评论 -
反转链表
题目描述输入一个链表,反转链表后,输出链表的所有元素。算法: 前中后三个指针,中指针指向前节点,然后前结点和中结点向后移动,直到middle =NULL测试: 1、空链表 2、只有1个结点的链表注意: 先更新front = middle 再更新middle = lastclass Solution {public: ListNode* ReverseList(ListNode*原创 2016-07-07 22:00:07 · 213 阅读 · 0 评论 -
调整数组顺序使奇数位于偶数前面
题目描述输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。算法分析: 1、使用双指针,分别指向数组首尾。 2、移动P1,直到指向偶数;移动P2,直到指向奇数 3、交换数字。 4、循环直到P2class Solution {public: void reOrder原创 2016-07-07 10:57:20 · 241 阅读 · 0 评论 -
o(1)时间删除链表指定结点
一、常规删除方法 o(n) 算法: 1、不需改变链表结构 2、从头开始遍历结点,找到待删除结点的前一个结点。二、O(1) 算法: 1、改变链表结构,并且不能是尾节点。给定要删除节点的地址。 2、不一定非得要找到被删除结点的前一个结点,可以很方便的找到待删除结点的下一个结点,将下一节点内容复制到待删除结点,删除下一节点即可。 3、如果是根据内容删除结点,则不能使用。struct List原创 2016-07-07 10:10:02 · 298 阅读 · 0 评论 -
数值的整数次方
题目描述给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。算法: 1、考虑指数可能为负数或0;考虑底数可能为0的情况2、由于计算机表示小数(包括float 和 double型小数)都有误差,不能直接使用等号判断相等。如果浮点型数差的绝对值很小,可认为相等。3、乘法可以用左移2代替 n<<2 除法可以用右移2代替 n>>24、优化整数次方原创 2016-07-06 20:45:41 · 350 阅读 · 0 评论 -
程序测试
代码测试: 1、功能测试 普通功能测试,完成基本功能。 发散性思维,考虑功能可靠性,例如大数等。 2、边界测试 循环结束的边界条件,递归终止的边界条件,最大正整数,最大负整数等 3、负面测试 输入数据不符合要求原创 2016-07-06 10:38:52 · 640 阅读 · 0 评论 -
二进制中1的个数
题目描述输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。算法: 将输入的数不断右移,和1进行与运算,结果为1记一次。 劣势:如果有符号的负数,会右移带来很多符号1改进: 将1不断左移,和输入的数与运算class Solution {public: int NumberOf1(int n) { unsigned int number = 1;原创 2016-07-06 10:04:34 · 205 阅读 · 0 评论 -
斐波那契变化题目
1、青蛙跳台阶问题 题目描述: 一只青蛙一次可以跳上1级台阶,也可以跳上2级。求跳上n级台阶总共有多少种跳法。算法: a、n=1,只有一种跳法。 b、n=2,两种跳法。 如果在n级台阶的时候,可能是从n-2级跳2级上来的,也可能是从n-1级跳1级上来的。 所以:f(n) = f(n-1) + f(n-2)2、小矩形覆盖大矩形问题可以横也可以竖。算法: 先把右边的大矩形2x8的覆盖方法记原创 2016-07-05 22:42:29 · 322 阅读 · 0 评论 -
旋转数组
题目描述把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。 NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。算法: 核心思想:两个子数组的分界点,就是最小值的位置。1、旋转n个: 旋转数组,即变成两个递增子数组,且前原创 2016-07-05 22:08:11 · 374 阅读 · 0 评论 -
重建二叉树-剑指offer
题目描述输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。算法: 前序遍历的第一个点是树的根节点,然后在中序遍历中找到此根节点,分为2部分,左边为左子树,右边为右子树。class Solution {public原创 2016-07-01 10:02:33 · 294 阅读 · 0 评论 -
剑指offer-数组查找
题目描述在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。 输入描述: array: 待查找的二维数组 target:查找的数字输出描述: 查找到返回true,查找不到返回falseclass Solution {public: bool Find(vector<v原创 2016-06-30 10:08:00 · 362 阅读 · 0 评论 -
剑指offer-字符串
1、常量字符串 为了节省内存,C++会把常量字符串放到单独一个内存区域。当有指针赋值给相同常量字符串时,他们会指向相同的内存地址。int main(){ char str1[] = "hello world"; char str2[] = "hello world"; if(str1 == str2) cout<<"str1 and str2 are sam原创 2016-06-30 22:31:43 · 357 阅读 · 0 评论 -
栈和队列-剑指offer
操作系统会给每个线程创建一个栈用来存储函数调用时各个函数的参数、返回地址和临时变量。题目:用2个栈实现队列 题目描述用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。stack1保存新插入的数据 stack2保存待删除的数据插入步骤:将数据插入到stack1中 删除步骤:当stack2空时,将stack1中所有的数据导入stack2; 当stack2不空时,原创 2016-07-01 10:27:28 · 290 阅读 · 0 评论 -
两个队列实现一个栈-剑指offer
队列特点:先进先出,尾部插入数据,头部输出数据 栈特点:后进先出,尾部插入数据,尾部输出数据算法: 插入数据:插入到有数据的队列的尾部,如果都空就选1个 删除元素:将有数据的队列中前边所有数据转移到另一个队列,然后删除数据。原创 2016-07-01 10:46:04 · 269 阅读 · 0 评论 -
归并排序-剑指offer
算法: 分治法,先不断的二分,直到有序,第一次有序就是数组里只有一个数字。 然后递归合并数组,需要有辅助空间暂存合并后的数组,再更新原数组。分:void MergeSort(int a[],int first,int last,int temp[]){ if(first<last){ int mid = (first + last)/2; MergeSor原创 2016-07-04 10:13:52 · 597 阅读 · 0 评论 -
合并两个排序的链表
题目描述输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。算法: 设定一个合并后的链表的头指针new,每次都比较1,2链表的第一个节点,让new指针指向比较小的节点。然后1,2指针向后走。测试: 空链表struct ListNode { int val; struct ListNode *next; ListNode(int x)原创 2016-07-07 22:29:18 · 90 阅读 · 0 评论 -
树的子结构
题目描述输入两颗二叉树A,B,判断B是不是A的子结构。子结构:树B是A中的一部分算法: 第1步、A中某节点值与B根节点值相同进去2步,不相同继续先根遍历树A,继续和B的根节点比较。 第2步、先根遍历检验所有结点是否相同,结束条件为B树全部访问。class Solution {public: bool HasSubtree(TreeNode* pRoot1, TreeNode* pRoo原创 2016-07-08 19:01:14 · 228 阅读 · 0 评论 -
二进制小数
十进制小数转其他进制小数:二进制对十进制小数乘2得到的整数部分和小数部分,整数部分既是相应的二进制数码,再用2乘小数部分(之前乘后得到新的小数部分),又得到整数和小数部分. 如此不断重复,直到小数部分为0或达到精度要求为止.第一次所得到为最高位,最后一次得到为最低位 如:0.25的二进制 0.25*2=0.5 取整是0 0.5*2=1.0 取整是1 即0.25的二进制为 0.01 (原创 2016-08-06 21:04:36 · 1311 阅读 · 0 评论 -
最近公共祖先
题目描述有一棵无穷大的满二叉树,其结点按根结点一层一层地从左往右依次编号,根结点编号为1。现在有两个结点a,b。请设计一个算法,求出a和b点的最近公共祖先的编号。 给定两个int a,b。为给定结点的编号。请返回a和b的最近公共祖先的编号。注意这里结点本身也可认为是其祖先。 测试样例: 2,3 返回:1算法: 因为是满二叉树,所以下标有规律可循:哪一个分支大,哪一个除2向上找父节点,直到相原创 2016-08-06 11:58:57 · 283 阅读 · 0 评论 -
输出树单层结点
题目描述对于一棵二叉树,请设计一个算法,创建含有某一深度上所有结点的链表。 给定二叉树的根结点指针TreeNode* root,以及链表上结点的深度,请返回一个链表ListNode,代表该深度上所有结点的值,请按树上从左往右的顺序链接,保证深度不超过树的高度,树上结点的值为非负整数且不超过100000。class TreeLevel {public: ListNode* getTreeL原创 2016-08-06 10:25:58 · 284 阅读 · 0 评论 -
有向路径检查
题目描述对于一个有向图,请实现一个算法,找出两点之间是否存在一条路径。 给定图中的两个结点的指针UndirectedGraphNode* a,UndirectedGraphNode* b,请返回一个bool,代表两点之间是否存在一条路径(a到b或b到a)。算法: 广度优先遍历。因为是有向图,所以以a开头遍历一次,以b开头遍历一次。 遍历的过程中如果找到了另一个结点,说明有路径,如果遍历结束后扔原创 2016-08-06 00:00:35 · 454 阅读 · 0 评论 -
判断字符串是不是一个字符串的翻转
算法: 1、翻转字符串:首尾指针交换 2、部分翻转:两部分分别翻转,再整体翻转。共翻转三次得到部分翻转 3、本题就是找每一个位置进行部分翻转,检查是否是另一字符串的翻转。class ReverseEqual {public: string reverse(string str){ if(str == "") return str;原创 2016-08-05 11:46:12 · 538 阅读 · 0 评论 -
BST判断
算法:中序遍历树,如果是严格升序的序列,则是,否则不是BSTclass Solution {public: bool flag = true; bool isValidBST(TreeNode *root) { if(root == NULL) return true; long pre = LONG_MIN;原创 2016-08-04 16:19:39 · 513 阅读 · 0 评论 -
Insert Delete GetRandom O(1)
Design a data structure that supports all following operations in O(1) time.insert(val): Inserts an item val to the set if not already present. remove(val): Removes an item val from the set if present原创 2016-08-04 11:52:09 · 1270 阅读 · 4 评论 -
Recover Binary Search Tree
Two elements of a binary search tree (BST) are swapped by mistake.Recover the tree without changing its structure.算法:中序遍历二叉树,如果后边的数边前边的小,则说明出错了。如果没有找到第二个结点说明是相邻位置出错了。class Solution {public: bool f原创 2016-08-03 22:42:42 · 219 阅读 · 0 评论 -
二叉树中和为某一值的路径
题目描述输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。算法: 前序遍历访问某一节点时,将值累加。 1、如果该结点为叶节点并且累加和等于target输出结果 2、如果该结点为叶节点但累加和不等于target则不输出结果 3、如果该结点非叶节点则继续遍历PS:需要注意的是处理完本节点后,都该将PATH和原创 2016-07-09 16:00:51 · 214 阅读 · 0 评论 -
找到链表倒数第K个结点
代码鲁棒性,防御性编程 考虑输入的各种情况,空指针,空字符串等 多考虑可能出现的状况题目描述输入一个链表,输出该链表中倒数第k个结点。算法: 1、鲁棒性检查: 输入链表为空; k=0或K比链表长度还大 删除的节点是表头2、快慢指针,fast先走K,然后同时出发,fast到尾节点,first指向删除结点。class Solution {public: ListNode* Find原创 2016-07-08 11:44:27 · 326 阅读 · 0 评论 -
二叉搜索树的后序遍历序列
题目描述输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。算法: 二叉搜索树后续遍历特点:最后一个值为根节点,从前到后,比根节点值小的是左子树,比根节点大的值为右子树。true条件:遍历整个树 false条件:不满足二叉搜索树定义时。class Solution {public: bool Veri原创 2016-07-09 10:46:27 · 277 阅读 · 0 评论 -
栈的压入、弹出序列
题目描述输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。算法: 题目主要需求为判断弹出序列是否可能存在,要求分析栈的能力。可以主要关注弹出序列。 因为栈是后进先出结构,弹出序列的当前原创 2016-07-08 22:44:15 · 291 阅读 · 0 评论 -
包含min函数的栈
题目描述定义栈的数据结构,请在该类型中实现一个能够得到栈最小元素的min函数。要求所有要求都是O(1)时间复杂度算法: 定义辅助最小栈,当新入栈元素小于当前栈内最小值时,辅助栈压入新入元素;当大于当前栈内最小值时,辅助栈压入当前最小值。弹栈时,同时弹出辅助栈元素。class Solution {private: stack<int> MinStack; stack<int> R原创 2016-07-08 21:57:11 · 193 阅读 · 0 评论 -
二叉树的镜像
题目描述操作给定的二叉树,将其变换为源二叉树的镜像。 输入描述: 二叉树的镜像定义:源二叉树 8 / \ 6 10 / \ / \ 5 7 9 11 镜像二叉树 8 / \ 10原创 2016-07-08 19:44:56 · 222 阅读 · 0 评论 -
快速排序-剑指offer
算法: 分治法void QuickSort(int s[],int left, int right){ if(left<right){ int i = left; int j = right; int key = s[left]; while (i<j) { //从右向左,找到比key小原创 2016-07-04 11:00:39 · 361 阅读 · 0 评论 -
堆排序-剑指offer
#include <iostream>#include<stack>#include<algorithm>using namespace std;//调整堆void HeapAdjust(int a[],int i ,int size){ //i的左孩子节点序号 int lchild = 2*i; //i的右孩子节点序号 int rchild = 2*i+1原创 2016-07-04 22:08:18 · 381 阅读 · 0 评论 -
二分查找-剑指offer
二分法要求,有序 分治法: 每次都和中间数字比,不断2分。int BinarySearch(int a[],int low,int high,int target){ if(low > high) return -1; int mid = (low + high)/2; if(a[mid] > target) return BinarySe原创 2016-07-04 22:43:12 · 315 阅读 · 0 评论 -
数组中只出现一次的数字
题目描述一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。算法: 如果一个数组里只有一个数字出现了一次,其余数字都出现两次的话,可以直接使用异或方法。因为异或就是相同为0,不同为1。对于此题使用异或最合适,出现两次的数最后对结果都是0没有贡献,留下的数字就是出现一次的数字。题目中是有两个数字出现一次,可以通过一次异或的结果将数组拆成两个子数组。方法是找到异原创 2016-07-11 21:04:02 · 277 阅读 · 0 评论 -
二叉树的深度,平衡二叉树深度
题目描述输入一棵二叉树,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。算法: 1、如果树为空,则深度为0 2、如果树不是空,那么深度是左子树的深度+1或右子树的深度+1.class Solution {public: int TreeDepth(TreeNode* pRoot){ if(pRoot==NULL)原创 2016-07-11 19:26:20 · 3458 阅读 · 0 评论 -
数字在排序数组中出现的次数
二分查找算法可以用来在排序数组中快速查找一个数字。题目描述统计一个数字在排序数组中出现的次数。算法: 最简单的算法o(n) 因为题目是排序数组,所以自然想到二分查找算法。 第一轮,找到指定数字第一次出现的位置。找到指定数字后,要判断前边的数字是不是k,如果不是则说明这个位置的k是第一次出现的,如果仍然是k则继续向前寻找。 第二轮,找到指定数字最后一次出现的位置。找到k后,要判断后边的数字是不原创 2016-07-11 17:58:24 · 239 阅读 · 0 评论 -
两个链表的第一个公共结点
题目描述输入两个链表,找出它们的第一个公共结点。算法: 首先将连个链表尾部对齐。因为是单向链表,如果有公共结点的话,从公共结点开始后,所有结点均相同。 1、因为想从后向前遍历找不到第一个不同的结点,那么使用两个辅助栈将两个链表所有结点放入栈中,然后同时弹出即可找到第一个不同的结点。 需要使用辅助空间。2、 当两个链表长度相同时,可以设定两个指针同时从头开始遍历,当遍历到第一个相同的结点的时候原创 2016-07-11 16:27:51 · 233 阅读 · 0 评论 -
数组中的逆序对
题目描述在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007 算法: 可以使用归并排序的思路,将时间复杂度从n2−>nlognn^2 -> nlogn 具体思路: 大的在前边的数字对称为逆序对,在归并排序的过程中,如果前边数组的数大于后边数组的数原创 2016-07-11 15:59:11 · 345 阅读 · 0 评论 -
丑数
题目描述把只包含因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。算法: 最简单易想的算法是从第一个数开始,连续判断是不是丑数,判断的依据就是不断的除以2,3,5看看最后的结果是不是1,如果是则是丑数。否则不是。这种算法效率过低。改进的算法: 因为丑数肯定是由2,3,5组成的,原创 2016-07-10 21:23:47 · 260 阅读 · 0 评论
分享