代码改变世界

随笔分类 -  算法---分治法

逆序数的求法

2013-10-05 22:10 by youxin, 22412 阅读, 收藏, 编辑
摘要: 逆序数:也是就说,对于n个不同的元素,先规定各元素之间有一个标准次序(例如n个 不同的自然数,可规定从小到大为标准次序),于是在这n个元素的任一排列中,当某两个元素的先后次序与标准次序不同时,就说有1个逆序。一个排列中所有逆序总数叫做这个排列的逆序数。在一个排列中,如果一对数的前后位置与大小顺序相反... 阅读全文

统计一个数字在排序数组中出现的次数(二分法)

2013-10-04 00:54 by youxin, 2532 阅读, 收藏, 编辑
摘要: 问题:计一个数字在排序数组中出现的次数如: 整数数组arr,数组中元素的个数是n,数组arr已经排好序,要在arr中找到某个某个整数x出现的次数,比如arr[] = {1,2,2,3,5,10},找到2的出现次数就是2。问题分析:相必看到有序数组的字样,想到利用二分应该是很顺利成章的事了。我们可以利用二分搜索求出x在arr中出现的第一个位置lo和最后一个位置hi,然后计算hi-lo+1的值就是x在arr出现的次数了,当然也有可能x并没有在arr中出现过,这时hi和lo都等于-1。时间复杂度是两个二分的复杂度:2*O(log n)。/******************************* 阅读全文

二进制逆序方法

2013-10-03 04:46 by youxin, 3370 阅读, 收藏, 编辑
摘要: 逆序分析原题一个整数,可以表示为二进制的形式,请给出尽可能多的方法对二进制进行逆序操作。 例如:10000110 11011000的逆序为 00011011 01100001分析题目中说是一个整数,对它的二进制进行逆序。并不是一个01字符串,或者01的数组。那么我们该如何解决这个问题呢?方法还是比较多的,有的中规中矩、有的非常巧妙。我们要掌握中规中规的方法,见识更多的巧妙的方法。慢慢的,能够举一反三,在遇到新的问题时,能够有灵思妙想。最直接的方法直接的方法,很容易想到:有如下代码:直接的方法,很容易想到:有如下代码: int v = 111;int r = v;int s = 32; for 阅读全文

分治法解选择问题

2012-05-06 23:25 by youxin, 742 阅读, 收藏, 编辑
摘要: 选择问题: 求n个元素中的第k小的元素。算法如下:#include<stdio.h>void swap(int &x,int &y){ int t; t=x;x=y;y=t;}//在a[ left: right]中选择第k小的元素int select(int a[],int left,int right,int k) { int i,j,pivot; if(left>=right) return a[left]; pivot=a[left]; i=left+1; j=right; while(1) { while(a[i]<... 阅读全文

分治法求最大最小元素

2012-05-06 23:11 by youxin, 1750 阅读, 收藏, 编辑
摘要: 问题:在含n个元素的集合中寻找最大值和最小值。最常见的做法是:max=a[1];min=a[1];for(i=2;i<=n;i++) if(max<a[i]) max=a[i]; else if(min>a[i]) min=a[i];算法中需要比较N-1次,才能得到max,最好的情况是升序,不需要进行与min的比较, 共进行n-1次比较。最坏的情况是降序,要经过n-1次比较得到Min,共进行2*n-2次比较,至于在平均情况下,为3(n-1)/2;用分治法可以用较少的次数解决上述问题。1,将数据等分为2组,目的是分别选取其中的最大值和最小值2,递归分解直到每组元素的个... 阅读全文

归并排序(递归和非递归)和自然合并排序

2012-04-29 17:06 by youxin, 1458 阅读, 收藏, 编辑
摘要: 合并排序是一种分治法,实现上用了递归结构。过程是:先将待排序的元素分为两部分,一般是对等长度的两部分,称为左右L、R,先分别将L,R进行合并排序,然后将排序好的L、R合并在一起,则所有元素都有序。复杂度O(nlgn)。 #include<iostream> using namespace std; 阅读全文