算法
heqianqiann
每一个不曾起舞的日子都是对生命的辜负
展开
-
算法 字符串匹配之朴素算法和KMP算法及JAVA代码实现
暴力匹配算法假设现在我们面临这样一个问题:有一个文本串S,和一个模式串P,现在要查找P在S中的位置,怎么查找呢?如果用暴力匹配的思路,并假设现在文本串S匹配到 i 位置,模式串P匹配到 j 位置,则有:如果当前字符匹配成功(即S[i] == P[j]),则i++,j++,继续匹配下一个字符;如果失配(即S[i]! = P[j]),令i = i - (j - 1),j = 0。相当于每次匹配失败时原创 2017-06-02 10:31:12 · 2495 阅读 · 0 评论 -
剑指Offer FindNumberMoreThanHalf 找出数组中出现次数超过一半的数字
题目描述:数组中有一个数字出现次数【超过 不会等于】数组长度的一半,请找出这个数字思路:先对数组进行排序,出现次数超过一半的数组元素一定是该数组的中位数 这里使用效率比较好的双指针快排/** * 基于快排算法 */ public static int findNumberBySort(int[] array) { if (array == null原创 2017-08-18 17:05:32 · 761 阅读 · 0 评论 -
剑指Offer CountOneInBinary 计算二进制中1的个数
方法1:根据除2取余的方法判断1的个数原理:一个数除以2相当于右移一位 如果除的过程中有与 表示当前位置有一个1以10 100 010为例:第一次除以2 商是1 010 001 余数是0 第二次除以2 商是 101 000 余数是1代码实现: public static int countByDivide(int num) { int count = 0; whi原创 2017-07-10 08:27:10 · 421 阅读 · 0 评论 -
剑指Offer AccurateFactorial 计算精确的阶乘
题目描述:输入不超过1000的正整数n,输入n!=1*2*3..*n的精确结果思路: 初步计算1000!大概是4*10^2567 所以基本数据类型是无法保存这么大的数的 我们可以考虑使用数组保存 同时为了防止进位产生溢出 我们倒序从低位到高位保存,即f[0]是个位 f[1]是十位 f[2]是百位..public class AccurateFactorial { private static原创 2017-08-18 17:20:22 · 807 阅读 · 0 评论 -
剑指Offer CalCarryBit 计算进位个数
题目描述:计算两个整数相加时需要进行多少次进位 假设输入的整数都不超过9个数字思路:使用一个变量carry保存进位,一个变量count保存相加次数,每次将两个数的个位进行相加,大于10则count自增,注意每次将数和10取余就可以取到个位的数方法一: public static int calCarryNum(int num1, int num2) { if (num1 ==原创 2017-08-18 17:25:56 · 1137 阅读 · 0 评论 -
剑指Offer ReverseList 反转列表
题目描述:定义一个函数,输入一个链表的头结点,反转该链表并输出反转后链表的头结点。递归实现/** * 递归实现链表反转 从尾部开始处理 */ public static ListNode reverseListByRecursion(ListNode head) { ListNode prev = null; if (head == nul原创 2017-08-18 17:27:52 · 762 阅读 · 0 评论 -
剑指Offer MergeOrderedList 合并两个排序的链表
题目描述:输入两个递增排序的链表,合并这两个链表并使新链表中的结点仍然是按照递增排序的思路: 递归扫描两个数组 每次将next指针指向连个链表中当前节点的较小值public static ListNode mergeOrderedList(ListNode list1, ListNode list2) { if (list1 == null){ return原创 2017-08-18 17:32:12 · 691 阅读 · 0 评论 -
剑指Offer LevelTraversalTree 层序遍历二叉树
题目描述:从上往下打印二叉树的每个结点,同一层的结点按照从左到右的顺序打印。思路:1.循环+队列 每次扫描本层的所有节点放入队列 再从队头读取一个节点继续遍历子节点 public static void printByLoop(BinaryTreeNode root) { Queue<BinaryTreeNode> queue = new LinkedBlockingQueue原创 2017-08-21 13:52:59 · 865 阅读 · 0 评论 -
算法 递归和循环的转换
【直接转化 】 消除尾递归和单向递归 1. 尾递归 指在递归算法中递归调用语句只有一个 且处于算法的最后private static int factorialByRecurision(int num) { if (num == 1) { return 1; } return num * factorialByRecur原创 2017-08-23 15:31:45 · 2561 阅读 · 0 评论 -
算法 二分查找的变种以及注意事项
二分查找普通的二分查找public static int bSearch(int[] array, int num) { int low = 0, high = array.length; int mid; while (low <= high) { mid = low + (high - low) / 2; if (array[mid] ==原创 2017-09-02 15:25:06 · 1407 阅读 · 2 评论 -
算法 卡特兰Catalan数
介绍Catalan数是组合数学中一个常在各种计数问题中出现的数列。一般项公式为 Cn的另一个表达形式为一般来说,我们编程时使用递推关系会更方便计算或即:C(n) = C(1)*C(n-1) + C(2)*C(n-2) + … + C(n-1)C(1).它的前几项为: 1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796。可以先通过前几项判断问题是否属于卡特兰转载 2017-09-20 18:44:36 · 861 阅读 · 0 评论 -
剑指Offer RotateArray 旋转数组的最小数字
题目描述:把一个数组最开始的若干个元素搬到数组的末尾 我们称之为数组的旋转 输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素思路: 分析旋转数组的特点,例如{3,4,5,1,2},因为是旋转数组,因此不存在数组整个是递增序列。 最小元素的左边的是比它大的数且依次递增,右边同样的是比它大的递增序列,因此可以使用二分查找,三个指针分别指向首元素、尾元素和中间元素。当中间元素大于数组首元素原创 2017-08-18 16:53:34 · 489 阅读 · 0 评论 -
剑指Offer TurnOnLight 开灯问题
题目描述:有n盏灯,编号1-n.第1个人把所有的灯打开,第2个人按下所有编号为2的倍数的开关,第3个人关掉3的倍数的开关 依次类推 一共k个人 问最后哪些灯开着 /** * 输出开着的灯编号[从1开始] * * @param n 灯的总数 * @param k 人的总数 */ public static void calTurnOnLigh原创 2017-08-18 16:40:21 · 671 阅读 · 0 评论 -
算法 排序算法之交换排序--冒泡排序和快速排序
交换排序利用交换数据元素的位置进行排序的方法称为交换排序常用的交换排序方法有冒泡排序快速排序其中快速排序是一种分区交换方法[分治]冒泡排序[相邻交换 一次交换只能消除一个逆序]基本思想设数组a中存放了n个数据元素,循环进行n-1次排序第一次,依次比较相邻两个元素a[i]和a[i+1],若为逆序,则交换两个元素,这样进行n-1次排序后数值最大的数据放在数组的末尾第二次时,数据元素个数减1,操作方原创 2017-06-03 15:59:40 · 1489 阅读 · 0 评论 -
算法 排序算法之插入排序--直接插入排序和希尔排序
插入排序基本思想从初始有序的子集合开始,不断的把新的元素插入到已经排好序的子集合的合适位置上,使得子集合中数据元素的个数不断增多。当子集合等于集合时,插入排序算法结束。常用的插入排序有直接插入排序希尔排序直接插入排序基本思想顺序的把待排序的数据元素按照大小插入到已排序数据元素子集合的适当位置。子集合的数据元素个数从只有一个开始逐步递增到和集合大小相同时排序完毕排序过程代码实现C实现void I原创 2017-06-03 19:01:23 · 575 阅读 · 0 评论 -
算法 排序算法之选择排序--直接选择排序和堆排序
选择排序基本思想每次从待排序的数据元素中选取最大(最小)的数据元素放到数组的最前(最后),数据元素集合不断缩小,当数据元素集合为空时排序结束。常用的选择排序有:直接选择排序堆排序堆排序是一种基于完全二叉树的排序直接选择排序基本思想从待排序的集合中选取最小的数据元素并将它原始集合中第一个元素进行交换位置,然后从不包括第一个位置的数据元素集合中选取关键字最小的元素和原始集合中第二个数据元素交换位置原创 2017-06-03 21:21:26 · 480 阅读 · 0 评论 -
算法 排序算法之归并排序
归并排序归并排序主要是二路归并排序基本思想设数组a中存放了n个数据元素初始时把它们看成n个长度为1的有序子数组,然后从第一个子数组开始,把相邻子数组两两合并,得到n/2的整数上界个长度为2的新的有序子数组(当n为奇数时最后一个新的有序子数组的长度为1)对这些新的有序子数组再两两合并,直到最后长度为n的有序数组位置排序过程以数组{50,10,90,30,70,40,80,60,20}为例代码实原创 2017-06-03 22:40:51 · 518 阅读 · 0 评论 -
算法 排序算法之基数排序
基数排序基数排序也称作桶排序,是一种当关键字为整数类型时非常高效的排序方法。基本思想设待排序的元素是m位d进制整(不足m位的关键字在高位补0),设置d个桶,令其编号分别为0,1,2…d-1。首先元素最低位的数值一次把各个元素放到相应的桶中然后按照桶号从小到大和进入桶中数据元素的先后次序收集分配在各个桶中的数据元素。这样就形成了数据元素集合的一个新的排列,称这样的一次排序过程为一次基数排序。再对一次基原创 2017-06-04 14:16:20 · 893 阅读 · 0 评论 -
算法 排序算法之时间复杂度和空间复杂度
算法 时间复杂度 空间复杂度 稳定性 冒泡排序 最好:O(n) 最坏:O(n^2) 平均:O(n^2) O(1) 稳定 快速排序 最好:O(nlog(n))最坏:O(n^2) 平均:O(nlog(n)) O(log2n) 不稳定 直接选择排序 最好:O(n^2) 最坏:O(n^2) 平均:O(n^2) O(1) 不稳定 堆排序 最好:原创 2017-06-04 14:34:10 · 405 阅读 · 0 评论 -
算法 埃氏筛法求素数个数
思路原理要得到自然数n以内的全部素数,必须把不大于根n的所有素数的倍数剔除,剩下的就是素数。给出要筛数值的范围n,找出以内的素数。先用2去筛,即把2留下,把2的倍数剔除掉;再用下一个质数,也就是3筛,把3留下,把3的倍数剔除掉;接下去用下一个质数5筛,把5留下,把5的倍数剔除掉;不断重复下去……。题目:设函数f(n)返回从1-n之间素数的个数。nowcoder 发现:f(1) = 0f(1原创 2017-07-07 09:46:21 · 1695 阅读 · 0 评论 -
剑指Offer 二叉树的镜像
题目描述: 请完成一个函数,输入一个二叉树,该函数输出它的镜像。思路: 遍历二叉树 如果当前节点存在左子树和右子树 那么将两个子树进行交换1) 递归实现package com.hqq.exercise.tree;/** * MirrorTree 二叉树的镜像 * 题目描述: * 请完成一个函数,输入一个二叉树,该函数输出它的镜像。 * 思路: * 遍历两个二叉树 如果当前节点存在子节点原创 2017-08-13 18:48:55 · 425 阅读 · 0 评论 -
剑指Offer 含有Min函数的栈
题目描述: 定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的min函数在该栈中,调用min、push及pop德尔时间复杂度都是O(1)思路: 1. 在栈中定义一个标识最小变量的变量 每次入栈的时候进行比较判断 保证该变量保存的始终是入栈元素中的最小值 出现问题:如果该最小元素出栈? 2. 使用一个栈保存入栈的数据元素,再使用一个栈辅助保存最小值 以及定义一个变量表示当前还在栈中所原创 2017-08-13 20:11:11 · 287 阅读 · 0 评论 -
剑指Offer 调整数组顺序使奇数位于偶数前面
题目描述:输入一个整数数组 实现一个函数来调整该函数数组中数字的顺序,使得所有的奇数位于数组的前半部分 所有的偶数位于数组的后半部分思路:想到类似快排的实现,从前往后扫描偶数,从后往前扫描奇数,交换二者顺序即可。public static void order(int[] number) { int startIndex = 0; int endIndex = num原创 2017-08-18 16:24:54 · 530 阅读 · 0 评论 -
算法 一致性哈希算法
一致性哈希算法在1997年由麻省理工学院提出的一种分布式哈希(DHT)实现算法,设计目标是为了解决因特网中的热点(Hot spot)问题,初衷和CARP十分类似。一致性哈希修正了CARP使用的简 单哈希算法带来的问题,使得分布式哈希(DHT)可以在P2P环境中真正得到应用。 一致性哈希算法提出了在动态变化的Cache环境中,判断哈希算法好坏的四个定义:1.平衡性Balance 平衡性是指哈希的结转载 2017-10-03 23:43:11 · 1727 阅读 · 0 评论