数据结构与算法
ancientmoondjay
这个作者很懒,什么都没留下…
展开
-
《编程之法》:字符串的包含
题目给定一长字符串a和一短字符串b。请问,如何最快地判断出短字符串b中的所有字符是否都在长字符串a中。思路设一个整数hash,对于a中的每一位,通过’|’运算在二进制hash对应的位上置位。然后对于b中的每一位,通过’&’运算看是否hash中该位上是否有置位,以此来判断是否有包含该字符。代码bool StringContain(const string a,const string b) {原创 2017-03-17 22:11:18 · 361 阅读 · 0 评论 -
《C++实现数据结构》:二叉树
二叉树的定义以及性质在之前的博客里已经说过了,今天来用C++实现二叉树。提供先序遍历、中序遍历、后序遍历的递归和非递归的两种实现方式,也提供了层次遍历的用队列实现方式。详细的看代码学习吧,关键注释都有加上了。————————————————————2017.4.4补充———————————————————— 今天补充了反转二叉树的实现,提供递归和非递归两个版本。 ————————————————原创 2017-03-20 19:53:39 · 644 阅读 · 0 评论 -
编程实现整数和字符串的相互转换
一、整数 -> 字符串 思路:对每一位加’0’,再逆序。整数加’0’会被隐式转化成char。 代码:#include <iostream>using namespace std;//整数转换为字符串int main() { int i_num = 12345,i_i=0; string s_tmp,s_str; while (i_num) { s_tmp原创 2017-03-12 19:55:21 · 740 阅读 · 0 评论 -
C++实现排序算法
八大排序算法有直接插入排序、希尔排序、冒泡排序、快速排序、直接选择排序、堆排序、归并排序、基数排序。 今天想把排序算法系统学习一下,所以上网搜索了下排序算法。真是个好家伙,那么多!不怕,一个个学习并用代码实现出来! 排序算法大体可以分为以下几类:交换类排序:冒泡排序、鸡尾酒排序、奇偶换位排序、梳子排序、侏儒排序、快速排序、臭皮匠排序选择类排序:选择排序、堆排序、Smooth排序、笛卡尔树排序原创 2017-04-03 17:01:08 · 988 阅读 · 0 评论 -
《编程之法》:寻找和为定值的多个数
题目输入两个整数n和sum,要求从数列1,2,3,…,n中随意取出几个数,使得它们的和等于sum,请将其中所有的可能的组合列出来。思路这是个01背包问题。考虑是否取第n个数的策略,问题可以转化为一个只与前n-1个数相关的问题,也就是: (1)如果取第n个数,那么问题就转化为“取前n-1个数使得它们的和为sum-n” (2)如果不取第n个数,那么问题就转化为“取前n-1个数使得它们的和为sum”原创 2017-03-18 16:43:10 · 708 阅读 · 0 评论 -
字符串连续出现次数最多的子串
题目求字符串“abcbcbcaa”中连续出现次数最多的子串。思路将整个字符串分解为后缀字符串组,便于比较连续出现的子串。abcbcbcaa //第0行bcbcbcaa //第1行cbcbcaa //第2行bcbcaa //第3行cbcaa //第4行bcaa //第5行caa //第6行aa //第原创 2017-03-13 21:50:09 · 1738 阅读 · 0 评论 -
编程之法:字符串的排列组合
一、排列题目一输入一个字符串,打印出该字符串中字符的所有排列。例如,输入字符串“abc”,则输出由字符’a’、’b’、’c’所有排列出来的所有字符串”abc”、”acb”、”bac”、”bca”、”cab”和”cba”。思路从每个子串的第二个字符开始,依次与第一个字符交换,然后继续处理子串。也就是一个递归算法。如图所示(图是在网上找的): 另外,还要注意所给字符串中有重复字符的情况,可以增加一原创 2017-03-18 10:16:39 · 1007 阅读 · 0 评论 -
《编程之法》:寻找最小的k个数
题目标题有n个整数,请找出其中最小的k个数。思路维护一个容量为k的最大堆,用来存储最先遍历的k个数。建好堆后遍历剩余n-k个整数,将每次遍历到的新元素与堆顶做比较,若比堆顶小,则用该元素替换堆顶,然后更新堆。遍历结束后堆中的k个数即是最小的k个数。代码//// Created by huxijie on 17-3-18.// 寻找最小的k个数#include <iostream>using n原创 2017-03-18 12:24:55 · 287 阅读 · 0 评论 -
《编程之法》:寻找和为定值的两个数
题目输入一个整数数组和一个整数,在数组中查找一对数,满足它们的和正好是输入的那个整数。如果有多对数的和等于输入的整数,输出任意一对即可。思路一:无序则hash建立一张hash表,存储每个整数,然后遍历数组的前一半,在hash表中查找是否有sum-k的这个数存在。代码//// Created by huxijie on 17-3-18.// 寻找和为定值的两个数#include <iostream原创 2017-03-18 15:51:17 · 643 阅读 · 0 评论 -
《编程之法》:最大连续子数组和
题目给定一个整数数组,数组里可能有正数、负数和零。数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。求所有子数组的和的最大值。例如,如果输入的数组为{1,-2,3,10,-4,7,2,-5},那么和为最大的连续子数组为{3,10,-4,7,2},和为18。思路使用动态规划的思想。令currSum是以当前元素结尾的最大连续子数组的和,maxSum是全局的最大子数组的和,当往后扫描时,对第原创 2017-03-18 17:39:36 · 445 阅读 · 0 评论 -
《编程之法》:跳台阶
题目一个台阶总共有n级,如果一次可以跳1级、2级、3级。求总共有多少种跳法。思路如果整个台阶只有1级,则只有一种跳法; 如果台阶只有2级,则有两种跳法; 如果台阶只有3级,则有四种跳法。 推广到一般情况,记f(n)为n级台阶的跳法。当n>3时,第一次跳1级还是2级还是3级,决定了后面剩下的台阶的跳法数目的不同。如果第一次只跳1级,则剩下的n-1级台阶的跳法数目是f(n-1);如果第一次跳2级,原创 2017-03-18 19:29:42 · 477 阅读 · 0 评论 -
《编程之法》:奇偶数排序
题目给定一个整数数组,请调整数组中数的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分。思路学过快速排序的一看到这道题就会觉得非常熟悉。这根本就是快速排序中的划分算法的变种嘛。直接声明2个指针指向首尾,首指针往后扫,找到第一个偶数,尾指针往前扫,找到第一个奇数,然后交换,之后接着指针 往后往前扫。以此过程重复到两个指针相遇。代码//// Created by huxijie on原创 2017-03-18 19:46:56 · 907 阅读 · 0 评论 -
《编程之法》:荷兰国旗
题目现有n个红白蓝三种不同颜色的小球,乱序排列在一起,请通过两两交换任意两个球,使得从左至右的球依次为红球、白球、蓝球。思路这道题又是快速排序中的划分算法的变种,是一种三向切分,把球排序分成三堆。为了方便讨论,用数字0表示红球,1表示白球,2表示蓝球。声明三个指针begin、current、end,其中current指针用来遍历整个数组。对于current指针所指向的值,有三种情况: (1)当cu原创 2017-03-18 20:13:32 · 583 阅读 · 0 评论 -
实现用KMP算法匹配字符串
问题有一个字符串“ABCABABCABDA”,问该字符串里面是否包含“ABCABD”,是的话请求出下标位置。思路一、简单的想法 最容易想到的方法应该就是让target的第一个字符和pattern的第一个字符比较,如果不相等,则让pattern后移一位,直到target有一个字符,与pattern的第一个字符相同为止。接着比较target和pattern的下一个字符,如果在pattern匹配完之前,原创 2017-03-13 20:14:23 · 1003 阅读 · 0 评论 -
求0到n之间所有数字中1的个数和
题目计算4 000 000 000以内的最大的那个f(n)==n的值,函数f的功能是统计0到n之间所有数字中1的个数和。思路这道题需要解决2个问题,求数字1的个数和以及求最大的f(n)=n。 一、子问题1:求数字1的个数和 如果N是一位数,可以确定f(N)=1。 如果是二位数,如果 N=13,那么从 1 到 13 的所有数字:1、2、3、4、5、6、7、8、9、10、11、12、13,个位和十原创 2017-03-14 19:04:14 · 1273 阅读 · 0 评论 -
求字符串中重复出现的最长子串
题目找出字符串babcdabdabcdb中出现的相同且长度最长的字符串,输出它及其首字符的位置。思路注意这道题和上一篇的不同,上一篇是求字符串中连续出现次数最多的子串。 不过,这两道题都有共同点,都可以用后缀字符串组来帮助解决。 本题中先将字符串进行后缀分解,对得到的后缀子字符串组排序,然后比较相邻字符串的前驱,这样就可以求出最长的公共前驱了。代码//// Created by huxijie原创 2017-03-14 15:27:08 · 1803 阅读 · 0 评论 -
《编程之法》:兄弟字符串
题目如果两个字符串中的字符一样,出现次数也一样,只是出现的顺序不一样,则认为这两个字符串是兄弟字符串。如何判断两个字符串是兄弟字符串。思路建两个hash数组,分别记录两个字符串,然后比较两个数组的每一项是否相同,有不同的说明不是兄弟字符串。代码bool IsBrother(const string a,const string b) { if (a.length() != b.length(原创 2017-03-17 22:21:40 · 975 阅读 · 1 评论 -
字符串循环右移
问题: 编写一个函数,作用是把一个char组成的字符串循环右移m个。比如原来是”abcdefghi”,如果m=2,移位后应该是“hiabcdefg”。解法: (解法一)使用strcpyvoid rightShifting(char *cp_s, int i_step) { int i_n = strlen(cp_s)-i_step; char ca_tmp[strlen(cp_s原创 2017-03-12 22:13:50 · 448 阅读 · 0 评论 -
树的术语及性质
一、基本术语 若一个结点有子树,那么该结点称为子树根的”双亲”,子树的根是该结点的”孩子”。有相同双亲的结点互为”兄弟”。一个结点的所有子树上的任何结点都是该结点的后裔。从根结点到某个结点的路径上的所有结点都是该结点的祖先。结点:表示树中的元素。 结点的度:拥有子结点的个数。 叶子:度为0的结点。 树的度:树中结点的最大的度。 结点的层次:根结点是第一层,它的孩子结点是第二层,依次类推。原创 2017-03-19 14:37:47 · 622 阅读 · 0 评论 -
《C++实现数据结构》:堆栈
堆栈是限定插入和删除操作都在表的同一端进行的线性表,是后进先出(LIFO)的线性数据结构。#include <iostream>using namespace std;//堆栈基类template <typename T>class Stack{public: virtual bool IsEmpty() const = 0; //若栈空,则返回true virtual原创 2017-03-19 21:42:48 · 790 阅读 · 0 评论 -
《C++实现数据结构》:队列
队列是限定在表的一端插入,在表的另一端删除的线性表,是先进先出(FIFO)的线性数据结构。 队列基类如下:#include <iostream>using namespace std;//队列基类template <typename T>class Queue{public: virtual bool IsEmpty() const = 0; //若队列空,则返回true原创 2017-03-20 16:06:25 · 403 阅读 · 0 评论 -
《C++实现数据结构》:优先权队列
一个大小为n的堆是一棵包含n个结点的完全二叉树,该树中每个结点的关键字大于等于其双亲结点的关键字值。完全二叉树的根称为堆顶,若它的关键字值是整棵树上最大的,我们称之为最大堆。反之,就是最小堆。 如果要求每次从数据结构中取出的元素是具有最高优先级的元素,这样的数据结构被称为优先权队列。可见,堆是实现优先权队列的非常有效的数据结构。另外,因为堆的特性,我们还可以用堆来实现排序,也就是堆排序了。堆排序的原创 2017-03-20 20:51:06 · 477 阅读 · 0 评论 -
《C++实现数据结构》:线性表
线性表类模板如下,是顺序表类和链表类的基类。#include <iostream>using namespace std;//线性表基类template <typename T>class LinearList{protected: int n; //线性表的长度public: virtual bool IsEmpty() const = 0; //若线性表空原创 2017-03-19 20:50:21 · 894 阅读 · 0 评论 -
《C++实现数据结构》:哈夫曼树
首先我们先来明确几个概念。 树的路径长度:从根到树中任意结点的路径长度是指从根结点到该结点的路径上所包括的边的数目,也相当于是该结点的层次-1。 树的内路径长度:除叶子结点外,从根到树中其他所有结点的路径长度之和。 树的外路径长度:从根到树中所有叶子结点的路径长度之和。 叶子结点的加权路径长度:从根到该叶子的路径长度与叶子的权的乘积。 树的加权路径长度:树中所有叶子结点的加权路径长度之和。原创 2017-03-21 21:30:07 · 1955 阅读 · 0 评论 -
《C++实现数据结构》:二叉搜索树
设结点由关键字值表征,假定所有结点的关键字值各不相同,二叉搜索树或者是一棵空二叉树,或者是具有下列性质的二叉树: (1)若左子树不空,则左子树上所有结点的关键字值均不小于根结点的关键字值。 (2)若右子树不空,则右子树上所有结点的关键字值均大于根结点的关键字值。 (3)左、右子树也分别是二叉搜索树。 具体实现见代码,相关注释已写。//// Created by huxijie on 17-原创 2017-03-22 15:05:10 · 445 阅读 · 0 评论 -
《C++实现数据结构》:散列表
散列表通过将关键字值映射到表中某个位置上来存储元素。由给定的关键字值,根据映射,计算得到元素的存储位置来访问元素。 在散列技术中,冲突是指对于关键字集合中的两个关键字值Ki和Kj,当Ki != Kj时,有h(Ki)==h(Kj),h是散列函数。 目前比较常用的散列函数有:除留余数法、平方取中法、折叠法、数字分析法。 一个散列表中冲突是难以避免的,所以要寻求解决冲突的方法。拉链法和开地址法是两种原创 2017-03-22 21:00:27 · 1647 阅读 · 0 评论 -
《网易游戏2017互娱》实习笔试编程一:竖式填空
题目介绍:[编程|100分] 竖式填空 时间限制:1秒 空间限制:65536K 题目描述 小Q是名小学生,他最喜欢数学中的加法竖式填空了。例如下面的填空题,每个空格表示1…9中的一个数字。有时候这种竖式题不一定只有唯一解,小Q很想知道,给定一个这样的竖式,总共可能的解有多少个。 被加数和加数的位数不会超过3位。和的位数不会超过4位。空格只可能存在于被加数和加数中。输入描述: 每个输入数据原创 2017-03-12 16:37:58 · 812 阅读 · 0 评论 -
《C++实现数据结构》:图
图的内容非常多,边学习边写和图有关的算法也花费了不少时间与精力。写着写着最后都有近1000行代码了。orz…… 接下来详细说说和图有关的都有啥。一、相关概念图分为无向图和有向图。 在无向图中,若图中任意一对顶点都是连通的,则称此图是连通图。 在有向图中,若任意一对顶点u和v间存在一条从u到v的路径和从v到u的路径,则称此图是强连通图。 无向图的一个极大连通子图称为该图的一个连通分量。 有向原创 2017-03-29 21:34:32 · 8459 阅读 · 1 评论 -
《编程之法》:完美洗牌算法
题目有一个长度为2n的数组{a1,a2,a3,…,an,b1,b2,b3,…,bn},希望排序后变成{a1,b1,a2,b2,a3,b3,…,an,bn}。思路书上讲了先用完美洗牌算法将数组排序为{b1,a1,b2,a2,b3,a3,…,bn,an},然后再两两交换,就变为题目所要求的那样。 书上完美洗牌算法讲得很好,我这里就简单记录下。 注意,数组下标是从1开始存储要求排序的数据。 首先,对原创 2017-03-18 22:00:58 · 1670 阅读 · 0 评论