数据结构和算法
码到功成
智能时代的搬运工。
简书地址https://www.jianshu.com/u/107798e4d078
展开
-
n个数据的排列
递归实现:给定n个元素集合,打印这个集合所有可能的排列。例如给定{a,b,c},它的所有排列为{(a, b, c) (a, c, b) (b, a, c) (b, c, a )(c, a, b)(c, b, a)}。显然有n! 种分析: 1. a 跟{b, c }排列之后:a +{b,c}的排列 2. b 跟{a, c}排列之后: b+{a,c}的排列 3. c 跟{原创 2013-08-06 23:09:13 · 699 阅读 · 0 评论 -
单链表操作
这篇文章的目的只是为了自己复习单链表而写,里面的代码没有经过实际测试。只是好让自己保持思路。删除链表节点/* 单链表删除节点 */Node *del(Node *head, int num){ Node *p1, *p2; p1 = head; //先找到要删除的节点,再去判断其位置 while(num != p1->data || p1->next != NULL){原创 2015-03-13 21:27:02 · 477 阅读 · 0 评论 -
只遍历一次单链表找出中间节点的算法
要求:只遍历一次单链表找出中间节点的算法思路:设立两个指针,比如p0和p1, p0=p1=head。p0每次移动两个位置,p1每次移动一个位置,即p0=p0->next->next, p1=p1->next。当p0到达最后一个结点时,p1的位置便是中间节点位置。void searchmid(Node *head, Node *mid){ Node *p0, *p1; p1 = h原创 2015-03-13 21:41:23 · 1818 阅读 · 0 评论 -
统计字符串权重
题目:假设,字母’a’代表值为1(即value(a)==1), ‘b’为2,…,’z’为26;如果出现连续相同字符,如aaaa…(连续k个a),这k个a的总权值会变成k*k*value(),如BB和bbbb的权值都是4*4*2=32;分析:顺序扫描一次就可以统计出来,时间复杂度O(n), 额外空间复杂度O(1),注意处理大数及边界。第一行输入一个整数T(T<=1000),表示有T组数据。 接下来每原创 2015-04-19 21:59:47 · 2740 阅读 · 0 评论 -
求滑动窗口最大值
题目:给定一组序列和滑动窗口大小,找出滑动窗口中的最大值。例如,给定序列2,3,4,2,10,8,12和窗口大小3,滑动窗口最大值为 4,4,10,10,12.分析:暴力法:输入序列数为n,窗口大小为k。依次扫描滑动窗口求出其最大值,显然这种算法的时间在最坏的情况下时间复杂度为O(n*k).如何把时间复杂度降到O(n),这就需每次要找出窗口中最大值的时间复杂度为O(1)。这种方法请参考剑指off原创 2015-04-13 11:34:17 · 1287 阅读 · 0 评论 -
经典位运算
位运算能节约内存和使用程序性能更好:用位运算实现两个 整型数的交换void exchange(int a, int b){ a ^= b; b ^= a; a ^= b;}用位运算实现取两个整数的(a+b)/2的向下取整值(或求均值)int average(int a, int b){ return (a&b) + ((a^b)>>1);}判断一个整数是否是2^N次原创 2015-03-17 22:26:44 · 613 阅读 · 0 评论 -
机器人的运动范围
题目:地上有一个m行n列的方格。一个机器人从坐标(0,0)的格子开始移动,它每次可以向左、右、上、下移动一格,但不能进入行坐标和列坐标的数位之和大于k的格子。例如,当k为18时,机器人能够进入方格(35,37),因为3+5+3+7=18。但它不能进入方格(35,38),因为3+5+3+8=19。请问机器人能够到达多少格子?分析:回溯算法经典入门例子。/* 机器人运动范围 */#include <i原创 2015-04-16 20:01:46 · 946 阅读 · 0 评论 -
最长连续子数组和为0
题目找出最长的连续子数组,其和为0。分析穷举法:两次扫描数组把所有的和为0的子数组长度均找出,然后再选择最大的。时间复杂O(n2)O(n^2)。改进:给定一个数组如,1, 2, 3, 4, -1, -2, -4, -3, 1, 1,1,1,1,求出其累加和数组1,3,6,10,9,7,3,0,1,2,3,4,5。顺序扫描数组,遇到0记录其索引值index,那么长度为index-0+1。如果遇到非0,原创 2015-09-26 16:23:51 · 2081 阅读 · 0 评论 -
二分查找算法(折半查找算法)
原理:二分查找算法也是一种分治算法,每次将规模变成一半。性能:它的本质是进行的二叉搜索树查找,所以最坏情况是时间复杂度即树高O(n) (最坏情况的查找次数logn+1向下取整)。缺点:只能查找有序表循环实现int binarySearch(int a[], int key, int n){ int p, r, mid; p = 0; r = n-1; w原创 2015-03-31 21:24:41 · 646 阅读 · 0 评论 -
计数排序
原理通过统计各个元素出现次数,以决定元素的位置。应用场景适合元素值不大,且重复较多的情况。计数排序的精髓在于通过统计次数进行排序,相比于比较排序算法,性能更佳。当适用场景有限,比如对公司员工按年龄排序等。性能时间复杂度仅O(n),空间复杂度O(n)。代码 /* 非常巧妙的实现 */ public static void countSort(int a[]){ if(a原创 2015-09-17 23:47:59 · 475 阅读 · 0 评论 -
猴子分桃子问题
题目题目:海滩上有一堆桃子,五只猴子来分。第一只猴子把这堆桃子凭据分为五份,多了一个,这只猴子把多的一个扔入海中,拿走了一份。第二只猴子把剩下的桃子又平均分成五份,又多了一个,它同样把多的一个扔入海中,拿走了一份,第三、第四、第五只猴子都是这样做的,问海滩上原来最少有多少个桃子?原创 2015-09-19 12:12:45 · 742 阅读 · 3 评论 -
归并排序算法
思路:把待排序序列分成相同大小的两个部分,依次对这两部分进行归并排序,完毕之后再按照顺序进行合并。具体思路请参考算法导论,以下实现按算法导论中思路来写的。性能:稳定的排序算法,时间复杂度最差、平均、最好都是O(nlogn),空间复杂度为O(n)。#include using namespace std;void mergeSort(int a[], int p, int r);vo原创 2015-03-16 10:02:15 · 458 阅读 · 0 评论 -
硬币组合问题
题目假设我们有8种不同面值的硬币{1,2,5,10,20,50,100,200},用这些硬币组合够成一个给定的数值n。例如n=200,那么一种可能的组合方式为 200 = 3 * 1 + 1*2 + 1*5 + 2*20 + 1 * 50 + 1 * 100. 问总过有多少种可能的组合方式?原题 转载分析这道题目是非常经典的动态规划算法题。给定一个数值sum,假设我们有m种不同类型的硬币v1,v2,原创 2015-09-19 16:57:28 · 1696 阅读 · 0 评论 -
最大子数组问题
题目:输入一个整型数组,数组里有正数也有负数。数组中一个或连续的多个整数组成一个子数组。求所有子数组的最大子数组和的最大值。思路:暴力法:n个元素的子数组(不为空)个数为n+(n-1)+...1 = 2*(n+1)*n/2个。时间复杂度至少为O(n^2)。动态规划法:如果已知a[0..j]的最大子数组,那么a[0..j+1]的最大子数组要么是a[0..j+1]的最大子数组,要么是a[i..原创 2015-03-20 21:11:13 · 664 阅读 · 0 评论 -
插入排序
思路:将待排序的关键字插入到已经排好序(只有一个元素也称排好序)的记录中性能:稳定排序算法,时间复杂度O(n^2),空间复杂度O(1)(就是指辅助空间),有大量数据移动,越有序越好性能越好(逆序性能最差),适合少量数据排序。void insert_sort(int a[], int n){ int j, key; for(int i = 1; i < n; i++){ key =原创 2015-03-20 10:28:57 · 403 阅读 · 0 评论 -
霍纳规则(Horner'ruler)算法
/* * 多项式A(x) = a[n]*x^n + a[n-1]*x^(n-1)+...+ a[1]*x^1 + a[0],直接计算时,效率并不高 * Horner'ruler规则:A(x) = (...(((a[n]*x + a[n-1])*x + a[n-2])*x + a[n-3])*x+...+ a[1])*x + a[0] * Horner'ruler使多项式求值所需乘法次数最少 */#原创 2013-08-07 20:46:14 · 5250 阅读 · 0 评论 -
Reverse Integer(leetcode)
题目:整数反转Reverse digits of an integer.Example1: x = 123, return 321Example2: x = -123, return -321题目很简单,但是有些问题要注意:If the integer's last digit is 0, what should the output be? ie, cas原创 2014-12-17 21:52:38 · 630 阅读 · 0 评论 -
ZigZag Conversion(leetcode)
题目:The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows like this: (you may want to display this pattern in a fixed font for better legibility)P A H NA P原创 2014-12-16 22:13:30 · 476 阅读 · 0 评论 -
String to Integer (atoi)
题目:实现atoi()函数。把字符串转换成相应的int型整数。注意:如果第一个非空格字符存在,是数字或者正负号则开始做类型转换,之后检测到非数字(包括结束符 \0) 字符时停止转换,返回整型数。否则,返回零。对于溢出处理是一个比较重要的问题。测试用例:空串“” “-+1” “0” 超过int最大值“2147483648” 等于int最小值“-2147原创 2014-12-18 21:41:55 · 626 阅读 · 0 评论 -
Palindrome Number(回文串)
题目:Determine whether an integer is a palindrome. Do this without extra space.分析:该题目来源于leetcode。回文串是一个正读和反读都一样的字符串,比如“level”或者“noon”等等就是回文串。当然整数形式的回文串也是类似的。但负数不是回文串。两种思路:按定义来,依次比较串的首尾,直到中原创 2014-12-21 20:36:04 · 671 阅读 · 0 评论 -
Longest Common Prefix(最长公共前缀)
题目:查找字符串数组的最长的公共前缀(简称LCP),eg:"ab" 、"abc"、"abdge"其LCP="ab"分析:本人思路很简单,先找到最小长度的字符串的,再遍历字符串数组,把它们的每一位都和最小串比较。时间复杂度O(m*c),m为串数的个数, 其中c为最小串长, 对于n其实际上相当于常数,所以其时间复杂度为为线性的O(m)。代码:class Solution {publi原创 2014-12-22 16:56:54 · 595 阅读 · 0 评论 -
Pascal's Triangle(帕斯卡三角形)
题目:Given numRows,generate the first numRows of Pascal's triangle(杨辉三角). For example, given numRows = 5, Return[ [1], [1,1], [1,2,1], [1,3,3,1], [1,4,6,4,1]]分析:非递归实现,类似于用数原创 2014-12-23 20:28:16 · 1402 阅读 · 0 评论 -
Pascal's Triangle(帕斯卡三角形)II
题目:给定一个索引值k, 返回帕斯卡三角形(杨辉三角) kth例如:k = 3,返回[1,3,3,1]要求:空间复杂度O(k).代码:class Solution {public: vector getRow(int rowIndex) { vector v, temp; //temp为辅助空间 if (rowIndex < 0) return v;原创 2014-12-24 21:29:13 · 657 阅读 · 0 评论 -
Remove Nth Node From End of List(从链表表尾删除第n个节点)
题目:Given a linked list, remove the nth node from the end of list and return its head.For example, Given linked list: 1->2->3->4->5, and n = 2. After removing the second node from the原创 2014-12-26 21:44:28 · 805 阅读 · 2 评论 -
Intersection of Two Linked Lists(交叉点)
题目:Write a program to find the node at which the intersection of two singly linked lists begins.(找到两个链表的交叉点)For example, the following two linked lists:A: a1 → a2原创 2014-12-26 22:30:19 · 680 阅读 · 0 评论 -
Fibonacci(斐波那契)数列实现
Fibonacci数列:f[0] = 0, f[1] = 1, 以及当n > 1时, f[n] = f[n-1] + f[n-2]。注意:所有算法本身并非原创#include #include #define MALLOC(p, n) \ if(!(p = malloc(n))){ \ perror("Insufficient memorry"); \ } /* recu原创 2013-08-14 22:08:38 · 925 阅读 · 0 评论 -
快速排序算法
思路:快速排序算法使用分治思想。算法导论上快速排序算法实现思路很清晰,现实现如下:分解:数组A[p..r]被划分为两个(可能为空)子数组A[p..q-1]和A[q+1..r],使得A[p..r]中的每一个元素都小于A[q],而A[q]也小于等于A[q+1..r]中的每一个元素。其中,计算下标q也是划分过程的一部分。解决:通过递归调用快速排序,对子数组A[p..q-1]和A[q+1..r]进原创 2015-03-16 11:13:02 · 511 阅读 · 0 评论 -
找top 10信息
本文章内容来源于《程序员面试宝典》。题目:有1千万条短信,以文本文件的形式保存,一行一条,有重复。请用5分钟时间,找出重复出现最多的前10条。解析:某些面试者想用数据库的办法来实现:首先将文本导入数据库,再利用select语句某些方法得出前10条短信。但实际上用数据库是满足不了5分钟解决这个条件的。这是因为1千万条短信即使1秒钟录入1万条(这已经算是很快的数据录入了)5分钟才300原创 2015-03-14 22:45:27 · 868 阅读 · 0 评论