随笔分类 -  算法

摘要:1. 两个有序链表的合并(递归) PS:还有非递归算法思路: 递归的思路主要是两个有序的链表,从头结点开始比较,大的作为合并后的头结点, 比如list1 和 list2, 而除去头结点后的用list1' 和 list2'表示,若list1头结点大于list2的,则保留list1的头结点作为合并后链表的头结点, 而后用 list1'和 list2继续递归合并。代码如下:Nod* meg(Nod* list1, Nod* list2){ Nod* temp = NULL; if (list1 == NULL&&list2 == NULL) { return 阅读全文
posted @ 2013-04-20 17:33 Itachi7 阅读(178) 评论(0) 推荐(0)
摘要:(把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个排好序的数组的一个旋转,输出旋转数组的最小元素。例如数组{3, 4, 5, 1, 2}为{1, 2, 3, 4, 5}的一个旋转,该数组的最小值为1)除了正常情况,还要注意考虑三种特殊情况:(1). 数组是没有发生过旋转的 {1,2,3,4,5,6}(2). 全相等的数组 {1,1,1,1,1,1}(3). 大部分都相等的数组 {1,0,1,1,1,1}二分查找的思路,最开始 如果数组没有旋转过,直接返回第一个元素,就是最小的元素; 如果旋转过,再按后续首先获得 mid。 此时 ,若 (1) 如果 ar[mid] &g 阅读全文
posted @ 2012-09-28 09:30 Itachi7 阅读(346) 评论(0) 推荐(0)
摘要:常规解法:int trim(char* str){ int count = 0; char* p = str; bool first = true; while(*str != '\0' && *str == ' '){ count++; str++; } if(*str == '\0'){ *p = '\0'; return count; } while(*str != '\0'){ while(*str... 阅读全文
posted @ 2012-09-25 22:22 Itachi7 阅读(2489) 评论(0) 推荐(0)
摘要:递归转非递归 几乎都是用栈, 前序和中序遍历比较简单 ,后序遍历稍麻烦;1. 前序遍历 :void preDis(NODE* head) //前序遍历{ NODE* temp = head; stack<NODE*> st; while (temp != NULL||!st.empty()) { while (temp != NULL) //当前非空 { cout<<temp->val<<' '; //访问 ... 阅读全文
posted @ 2012-09-25 10:20 Itachi7 阅读(310) 评论(0) 推荐(0)
摘要:给定数组 如{5,8,3,1} 则有<5,3><5,1><8,3><8,1><3,1> 5个逆序对给定数组 求其逆序对的个数思路:归并排序 O(NlogN) 时间复杂度 O(N) 空间复杂度代码:int num = 0; //逆序对个数void mergg(int ar[],int low,int mid,int high){ int* b = new int[high + 1]; //b[] 复制 ar[] for (int i = low;i <= high;++i) { b[i] = ar[i]; } i... 阅读全文
posted @ 2012-09-20 10:00 Itachi7 阅读(5387) 评论(0) 推荐(3)
摘要:1.有一个整数数组,请求出两两之差绝对值最小的值,记住,只要得出最小值即可,不需要求出是哪两个数。思路:若有a[n]个数 构造b[n] 其中 b[i] = a[i] - a[i -1] 这样a[n]中任意两个数之差 就可以用 b[i] +...+b[j] = (a[i]-a[i-1])+(a[i+1]-a[i])..+(a[j]-a[j-1]) = a[j]-a[i-1]因此 再利用最大连续子序列和的类似方法O(n) 即可求出 (还是有问题 当数组为 {1,20,200,16,1}这种情况时 )int GetMinAbsoluteSubsequence(int B[],int begin,i. 阅读全文
posted @ 2012-09-10 23:56 Itachi7 阅读(492) 评论(0) 推荐(0)
摘要:假设前序 char pstr[] = "abdcef" 中序为 char mstr[] = "dbaecf" 构造该二叉树递归思想,首先前序遍历的第一个一定是根结点,然后从中序遍历中找到根节点所在的位置,这样就将中序分为左右子树的两部分,比如,首先找到先序的第一个'a', 在中序遍历中的位置,那么'db' 'ecf' 就分别为'a' 的左子树和右子树, 然后继续递归求解即可;void rebuild(char* ps,char* ms,int len,Node* &temp){ if 阅读全文
posted @ 2012-09-04 23:45 Itachi7 阅读(450) 评论(0) 推荐(0)
摘要:深搜 回溯bool isprimer(int tt) //判断该数是否为质数{ if (tt == 2||tt == 3) { return true; } else if (tt == 1||tt%2 == 0) return false; for (int i = 2;i <= sqrt(static_cast<double>(tt));++i) { if (tt%i == 0) return false; } return true;}bool test(int ... 阅读全文
posted @ 2012-09-03 20:21 Itachi7 阅读(541) 评论(0) 推荐(0)
摘要:给定一个数组 a[n], 输出b[n], 其中 b[i] = a[0]*a[1]...*a[i-1]*a[i+1]*....a[n]; 其中不能用除法 复杂度要求O(n) out[0] = inpt[0]; for (int i = 1;i < n;++i) //顺时第一趟 { out[i] = out[i - 1]*inpt[i]; } //for (int i = 0;i < n;++i) //{ // cout<<out[i]<<' '; //} //cout... 阅读全文
posted @ 2012-08-30 23:08 Itachi7 阅读(191) 评论(0) 推荐(0)
摘要:题目描述:给定一个二维矩阵包含正负数,求子矩阵中的和的最大值。例如:0 -2 -7 09 2 -6 2-4 1 -4 1-1 8 0 -2最大值为: 15 =9 2-4 1-1 8解题思路: [枚举上下界,转化为一维最大子序列和]由一维最大子序列和推广至二维: 假设我们已经知道最大子矩阵所在的高度(行)的上界和下界(起点行号和终点行号,eg [first,last]),然后我们再将相应上下界中每一列的和求出来,保存在数组b[i]中,这样就变成了求一维数组的最大子序列和的问题。PS: 在求每列之和时,可以用一个小技巧。对于某一上界 a_first, 不同的下界 b_first 对应的每列之和.. 阅读全文
posted @ 2012-08-13 10:52 Itachi7 阅读(273) 评论(0) 推荐(0)
摘要:给你4张牌 A-K 即[1,13] , 可以任意四种基本操作 + - * / 和 ( ) 优先级 判断是否可以计算得到24hits: 只会暴力解法, 4张牌 a,b,c,d 对应的组合一共有 4! = 24种 都是2目操作符 ,因此只需要3种操作, 一共有 4*4*4 = 64种 关于优先级,每次只有一对操作优先 包含2个操作数和一个操作符 ,因此,枚举所有优先情况也只有以下5种:包含逆波兰表达式(后缀表达式) 1. ((ab)c)d 00+0+0+ 2. (a(bc))d 000++0+ 3. (ab)(cd) 00+00++ 4. a((bc)d) 000+0... 阅读全文
posted @ 2012-08-06 20:26 Itachi7 阅读(245) 评论(0) 推荐(0)
摘要:有两个数组a,b,大小都为n,数组元素的值任意整形数,无序; 要求:通过交换a,b中的元素,使数组a元素的和与数组b元素的和之间的差最小。 当前数组a和数组b的和之差为 A = sum(a) - sum(b) a的第i个元素和b的第j个元素交换后,a和b的和之差为 A' = sum(a) - a[i] + b[j] - (sum(b) - b[j] + a[i]) = sum(a) - sum(b) - 2 (a[i] - b[j]) = A - 2 (a[i] - b[j]) 设x = a[i] - b[j] |A| - |A'| = |A| - |A-2x| 假设A > 阅读全文
posted @ 2012-07-17 14:35 Itachi7 阅读(5956) 评论(4) 推荐(3)
摘要:解题思路主要是从回文数的构造出发,貌似一般与回文数有关的都是构造回文数,而不是去搜索。分为多种情况:A. 该数的长度是奇数(只有1位很好办,除9外直接加1,9的话输出11),取出该数的前半截(包括中间数), 1.若该数是回文数,则用前半截数值加1,之后再构造新的回文数; 2.不是回文数,从中间往两边找到第一个不相等(因为不是回文数,所以肯定能找到)的数,若前面的小于后面的,则按1处理(用前半截数值加1,之后再构造新的回文数); 若前面的大于后面的,则直接用前半截来构造回文数。B. 该数的长度是偶数,取出前半截(正好是一半),思路和奇数的差不多, 如果是回文数或前半截小,则把前半截+1后... 阅读全文
posted @ 2012-07-03 11:39 Itachi7 阅读(4436) 评论(0) 推荐(0)