随笔分类 -  算法

1
摘要:最近在公司里基本处于打酱油的状态,工作正在交接中。没事又做起了算法题目。好久没怎么写算法题了,感觉手气还不错,经常能一次就写对(编译通过,得到想要的结果,没怎么测试),可能是因为这些题目之前看过或是写过,或许就是自己进步了一点。这15道大部分来自《剑指Offer》,作者的博客之前看过几次,感觉写得很 阅读全文
posted @ 2014-06-06 11:56 啊汉 阅读(20115) 评论(7) 推荐(6) 编辑
摘要:1:试着用最少的比较次数去寻找数组中的最大值和最小值。思路一:扫描数组两次,第一次等到最大值,第二次等到最小值。总共比较次数2N,这是大家都可以想到的。思路二:定义两个变量存放最大值和最小值,将数组两两分组,两两进行比较,大的和最大值进行比较,小的和最小值比较,数组两两比较次数是N/2,分别与最大值和最小值比较的次数为N,总共比较次数1.5N。好久没写算法了,于是蛋疼得想实现一下。//1:试着用最少的比较次数去寻找数组中的最大值和最小值。 void FindMaxMin(int *A,int size,int* Max,int* Min){ int i=(size & 1)?1:0; 阅读全文
posted @ 2013-03-28 10:35 啊汉 阅读(3977) 评论(11) 推荐(3) 编辑
摘要:1:多余的存储引用导致性能降低;2:利用局部性提高程序性能;先来说说引用是怎么降低程序性能,个人认为降低程序性能主要有两个原因,一是数据结构选择不合理,二是多层嵌套循环导致部分代码被多余重复执行。在第二种情况下我们一般都是优化循环最里层的代码,能提出来的尽量往外层提,实在不行的就优化它的运行速度。1:多余的存储引用导致性能降低。先来看一个关于引用导致性能降低的问题。下面两个方法哪个更快。 static void Test2(ref int sum) { for (int i = 1; i <= timer; i++) { ... 阅读全文
posted @ 2013-01-13 17:14 啊汉 阅读(3128) 评论(15) 推荐(10) 编辑
摘要:好久没有做算法题了,重温几个简单的算法题。第一题:求子数组的最大和这是一道很常见的算法题,很多人都能很快的写出算法,但很多人都不能写得完全正确,问题主要出在sum初始化上,很多错误的答案将他初始化为0,如果数组的所有元素都为负,那么得到的最大最是0,sum要初始化成数组的第一个元素。第二题:求1+2+…+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字以及条件判断语句 这道题在网上也有很多个版本,有在构造函数中实现加法,利用两个静态变量一个存结果,一个存当前值,然后创建一个一维n个元素的数组,存结果的静态变量即为所求,还有的就是用两个方法,一个方法是递 阅读全文
posted @ 2012-05-08 14:20 啊汉 阅读(7315) 评论(6) 推荐(5) 编辑
摘要:由于第一个版本想复杂了,思路不是很清新,导致有些问题没有攻克,过年那些天也想了很多,还是没有解决,一直想放弃那个解决方案,可就是舍不得放弃,我做了那么多,我想了那么久,我不想重头再来,但到最后还是没有找到既高效又没有明显BUG的解决方案,最终选择放弃第一版中的解决方案,今天本想用基于撒列的搜索树的方式实现的,可写了一部分代码后发现还是有些问题,当然并不代表用基于撒列的搜索树实现有问题,只是对于我来说有点难度,就算实现了也肯定不高效,最后也放弃了搜索树这个方案。最后想到的一个方案就是本篇博客讲的方案,思路很简单,还是基于撒列,把每个关键词的第一个字作为key,把关键词作为value,把所有关键词 阅读全文
posted @ 2012-01-31 16:21 啊汉 阅读(2754) 评论(6) 推荐(5) 编辑
摘要:等快递无聊--旋转字符串真是个无语的周末,昨天下午等了几个小时的快递,买了两本书《代码大全》和《编程珠玑》,还有别人的衣服,今天一大早又跑到公司来等快递,又是别人的衣服,还没有到呢,做专业的代购真是无语,本想买票,12306更让我无语,想登陆门都没有,只好玩玩程序,昨天看了编程珠玑,里面有个问题是关于字符串的旋转的,题目如下:将一个N元一维向量左旋i个位置,例如当n=8且i=3时,向量abcdefgh旋转为defghabc。你能否仅用数十个额外字节的存储空间,在正比于n的时间内完成向量的旋转废话就不多说了,其他垃圾的方法都直接PASS,直接看最好最正确的方法,没有时间写这些方法,也没有更多的时 阅读全文
posted @ 2012-01-08 11:47 啊汉 阅读(2019) 评论(6) 推荐(1) 编辑
摘要:递归再一次让哥震惊了先说那两个让哥震惊的递归问题:1:用递归实现单链表的倒序输出2:从二叉查找树中删除节点,并保证还是二叉查找树同学们可以开始思考这两个问题了,当然你可能N年前就遇到过这两个问题,那么不妨看看,看你是否真的理解了递归。实现这两个问题的代码当然很简单,就在下面。百度百科中递归的名片:递归做为一种算法在程序设计语言中广泛应用.是指函数/过程/子程序在运行过程中直接或间接调用自身而产生的重入现象.递归是计算机科学的一个重要概念,递归的方法是程序设计中有效的方法,采用递归编写程序能使程序变得简洁和清晰。刚开始学习的递归的时候,觉得他好强大,实现某些功能不用递归可能要几十行代码,用递归可 阅读全文
posted @ 2011-12-22 11:06 啊汉 阅读(7754) 评论(25) 推荐(6) 编辑
摘要:算法--两道百度笔试题 今天看到一位园友写了一篇关于百度的面试题的博客,成了评论头条,再下看了一下,非常感兴趣,那位博主的算法能力跟我一样需要提高,估计他的功力还在我之下,所以再下不才,在这里把自己的源码贴出来。 百度面试题(一):假设一整型数组存在若干正数和负数,现在通过某种算法使得该数组的所有负数在正数的左边,且保证负数和正数间元素相对位置不变。时空复杂度要求分别为:o(n)和o(1)。 其实开始的时候我也是一头雾水,在纸上画画之后发现,其实就是一道变形的插入排序。幸运的是这里不需要比较大小,要比较大小的话时间复杂度是O(n2),只用判断正负,那时间复杂度就只要O(n)了。 如:-3,1. 阅读全文
posted @ 2011-09-01 14:09 啊汉 阅读(17770) 评论(154) 推荐(6) 编辑
摘要:数组求和算法系列一直想写一个数组求和算法系列博客,但由于自己算法能力有限,完成不了,只能完成其中简单的部分,难的部分希望有园友愿意和我一起完成。在写这篇博客的过程中借用了别人的思路,有的的确是要一定的算法和数据结构基础,特别是对递归的理解,到现在为止我觉得我还没有真正的理解递归。我一向不太喜欢废话,我的博客要么是有关分析的,要么就是源码下面的代码希望对你有所帮助:1. 在排序数组中查找和为给定值的两个数字,输出一对代码//在排序数组中查找和为给定值的两个数字,输出一对void FineTwo(int*A,int size,int n) { if(n<1|| size<1) ... 阅读全文
posted @ 2011-08-24 12:36 啊汉 阅读(7431) 评论(7) 推荐(4) 编辑
摘要:四种方式实现--从尾到头输出链表 方法一:借用栈倒序输出链表 方法二:先翻转链表,再顺序输出 方法三:递归实现,一个字妙,两个字很妙,三个字太妙了 方法四:用数组实现 方法一:借用栈倒序输出链表 因为栈是先进后出,把链表中的元素存进栈中,链表前面的元素在栈底,后面的元素在栈顶,链表后面的元素先出栈 方法二:先翻转链表,再按顺序打印(主要是想自己实现单链表的翻转,这种实现方式破坏了链表的结构,当然再翻转一下就还原了) 翻转链表的步骤: 1:将当前节点的next节点指向他以前的前一个节点 2:当前节点下移一位 3:如果是最后一个节点,就把它的next节点指向它以前的前一个节点... 阅读全文
posted @ 2011-08-01 19:33 啊汉 阅读(5096) 评论(2) 推荐(2) 编辑
摘要:经典算法题--求对策字符串的最大长度(第二版)方法一:思路很中规中矩,遍历这个字符串,若有发现相邻的两个字符相等,就循环判断与这两个字符相邻的两个字符是否相等, 直到不等,记下字符符合条件的字符个数。最大的个数即为所求。(此方法适合如google这样的字符串)方法二:思路和方法一时一样的,适合ggoggle这样的字符串。方法三:满足题意,适合任何类型的字符串。就是时间复杂度为O(n^2)。方法一int counterplan1(conststring str) { int strlen=str.length(); int maxlen=0; ... 阅读全文
posted @ 2011-07-25 14:41 啊汉 阅读(1906) 评论(4) 推荐(1) 编辑
摘要:C++自己实现list 前两个博客发表了自己写的stack(栈)和queue(队列),感觉比较简单,今天想试着实现list,结果发现,不是那么容易,感觉自己对STL的底层不是很了解,真要自己实现还真的很难,看STL的源代码,那个晕啊...那代码也写得太难理解了,当然跟我不了解有关,但我相信,在将来的某一天我会懂的,你看我的代码也会懂的。 话说:STL中的list的内部结构就是一个双向链表,这个东东以前还真没有玩过,就凭他用的是双向链表我就不想用他,指针太多,耗资源,当然存在就有他的价值,他能快速访问其中的元素。废话总该少说,代码就该多些。 有那么一点高兴的是实现双向链表的翻转,其他的没什... 阅读全文
posted @ 2011-07-21 19:00 啊汉 阅读(8368) 评论(16) 推荐(3) 编辑
摘要:7种方式实现斐波那契数列一:递归实现 在学校里学习递归的时候,老师就喜欢举斐波那契这个例子,看!多简洁清晰。其实这个例子是非常不适合作为递归举例的, 原因就是效率太慢,除了最后一个数,每个数都被算了一遍又一遍,时间复杂度差不多是5n^2/3。二:数组实现 空间复杂度和时间复杂度都是0(n),效率一般,比递归来得快。三:vector<int>实现 时间复杂度是0(n),时间复杂度是0(1),就是不知道vector的效率高不高,当然vector有自己的属性会占用资源。四:queue<int>实现 当然队列比数组更适合实现斐波那契数列,时间复杂度和空间复杂度和vector&l 阅读全文
posted @ 2011-07-15 14:29 啊汉 阅读(22474) 评论(18) 推荐(5) 编辑
摘要:C++用数组和链表分别实现Stack C++学习有段时间了,感觉还是有很多不足啊,今天自己用数组和链表分别实现Stack,当然STL中的Stack肯定不是这么简单,你不妨看一下,说不定有收获呢,若发现有问题,请指正,毕竟对于C++我还是新手。数组版//typename可以表示任何类型,而class只能表示类template<typename T,typename container>class stack{public://栈是否为空bool empty( ) const{return index==0;}//出栈void pop( ){if(empty()){thrownew e 阅读全文
posted @ 2011-07-11 18:22 啊汉 阅读(5558) 评论(22) 推荐(2) 编辑
摘要:作者:陈太汉是的。我们讨厌产生临时变量,因为它要占用我们的内存,消耗我们的CPU时间,让我们的程序性能降低。但有时候它是必须的。那讨厌的临时变量什么时候产生呢?产生临时变量的三种情况:一:以By Value的方式传值;二:参数为const的类型。三:类型转换一:以By Value的方式传值。 我们都知道,引用类型和指针类型传递的都是地址,可以直接对地址中存放的数据进行操作, 而以传值的方式传递参数,就会在heap中重新分配一个临时区域, 将实参中的数据拷贝到临时区域中,而你对这分数据进行的任何的操作都不会影响实参的内容,因为实参跟形参只是内容相同, 分别在两块不同的内存中。而引用和指针操作的是 阅读全文
posted @ 2011-07-04 15:54 啊汉 阅读(4300) 评论(6) 推荐(1) 编辑
摘要:作者:陈太汉算法--找出数组中出现次数超过一半的数 每当我看到经典的算法题,就怀念高中,感觉很多算法题就是高中的题目,谁叫哥只读了个专科,高数基本相当没学。 有空要看看高数啊,想当年数学那是相当的......#include <iostream>using namespace std;class FindTheOne{public: 方法一 第一个想到的方法是见一个二维数组,一维存数组中的数据,二维存这个数出现的次数。出现次数最多的那个数就是要找的那个数 由于某个数出现的次数超过数组长度的一半,所以二维数组的长度只需要这个数组的一半。代码实现如下, 当然这个方法很糟糕,时间复杂度和 阅读全文
posted @ 2011-06-29 16:22 啊汉 阅读(19421) 评论(13) 推荐(3) 编辑
摘要:作者:陈太汉一个整数数组,长度为n,将其分为m份,使各份的和相等,求m的最大值 比如{3,2,4,3,6} 可以分成{3,2,4,3,6} m=1; {3,6}{2,4,3} m=2 {3,3}{2,4}{6} m=3 所以m的最大值为3算法 原理的思想是将大问题转换成小问题。就{3,2,4,3,6}的操作步骤: 第一步:想将数组递减排序得{6,4,3,3,2},求出数组中所有数的和m=18,第一个最大的数b=6, m/b=3余数为0,当除数为1,余数为0时终止。当余数不为0时,转到第三步。当余数为0时将数组划分为{6},{4,3,3,2}两个。把{4,3,3,2}看成一个新的数组。 第二步. 阅读全文
posted @ 2011-06-26 12:24 啊汉 阅读(8604) 评论(9) 推荐(1) 编辑
摘要:* 由于字符串的相加会产生了一个新的字符串,当有多个字符串相加时,就会不断的有字符串构造出来和被析构掉,当然这是相当耗资源的。* 所以就有了StringBuilder类。* StringBuilder的实现方式是这样的,默认分配16个字节的空间,如果追加的字符个数超过当前分配的空间,* 系统就重新分配一块两倍的空间,16,,32,64,128,256....。再把字符串的值拷贝到新的内存中。以前的内存等着垃圾回收器回收。* 这样也会有大量的内存被分配和回收。* 但StringBuilder可没有那么笨,它可以分配指定大小的连续内存用于存储字符串,如果指定的内存大小刚好容纳所有的字符串,* 那就 阅读全文
posted @ 2011-06-08 18:38 啊汉 阅读(1874) 评论(9) 推荐(2) 编辑
摘要:创建二叉查找树、查找二叉树中的某个节点、删除某个节点、 新增节点、查找某个节点的父节点、查找最小节点 对二叉树进行前序遍历、中序遍历、后序遍历 前序遍历,也叫先根遍历,遍历的顺序是,根,左子树,右子树 中序遍历,也叫中根遍历,顺序是 左子树,根,右子树 后序遍历,也叫后根遍历,遍历顺序,左子树,右子树,根 using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace SuanFa{ public class Order { //创建二分... 阅读全文
posted @ 2010-11-19 11:55 啊汉 阅读(808) 评论(0) 推荐(1) 编辑
摘要:一个数组存放了2n+1个整数,其中有n个数出现了2次,1个数出现了1次,找出出现1次的数是多少? //方法一:借助辅助数组(长度为n+1,元素为一结构体(包含数值和 //个数两个成员))进行计数,但是时间复杂度为O(n*n),空间复杂度为O(n+1) //本来是想把Val定义为结构体的,但由于结构体是值类型,不是引用类型, //添加到List结合中的元素的属性值不能被修改,把List中的一个元素赋给另一个Val,修改Val中的value和num, //List中对应的Val相关的属性值是不会改变的,因为他们是内存中的两个不同单元 //总之:谁叫我C学得不好,用的是C#呢,不然就用C实现了。 . 阅读全文
posted @ 2010-11-16 11:00 啊汉 阅读(646) 评论(3) 推荐(0) 编辑

1