(1)分治法:
算法:
1、如果A中只有一个元素,则该元素为主元素。否则,将数组A分为两部分A[i....mid],A[mid+1........A.length],分别求主元素p,q,则A的主元素一定为p或q中的一个
2、遍历数组A,求出与p,q相等的元素个数,如果>A.length/2,则为主元素。
T(n) = 1 n==1;
T(n) = 2T(n/2)+O(n)
得T(n) = O(nlogn)
(2)算法:
数列排序后位于最中间的那个数。如果一个数列有主元素,那么必然是其中位数。
求一个数列有没有主元素,只要看中位数是不是主元素。
找中位数的方法:
选择一个元素作为划分起点,然后用快速排序的方法将小于它的移动到左边,大于它的移动到右边。
这样就将元素划分为两个部分。
此时,划分元素所在位置为k。
如果k>n/2,那么继续用同样的方法在左边部分找;
如果k n/2
then print "主元素:" +median + "出现次数:" + cnt
else print "无主元素"
注意是平均时间复杂度E(T(n))
算法:
1、取第一个元素为a,遍历剩下元素,将>=a的元素添加到序列Big[]中,k,则求Small[]中的第k小的元素。
伪代码:
Search(A)
Input :String[m....n],k
Output:A[m...n]中的第K小的元素
a = A[1]
for i = 2 to n
if A[i] >= a then
add A[i] to Big[]
else
add A[i] to Small[]
if Small.length == k then
Output a
END
else if Small.length < k then
Search(Small[],k)
else
Search(Big[],k-1-Small.length)
(1)算法:
求A[1...n]的max and min 即求A[1...mid]和A[mid+1....n]的最大值和最小值,再比较后得到
(2)伪代码:
MAXMIN(A)
Input:A[i..j]
Output:max,min
if j-i+1 == 1 then Output A[i],A[i];END
if j-i+1 == 2 then
if A[i]2
=2+2(2+2T(n/4))
......
=2+2^1+2^2+.....+2^i+2^iT(n/2^i)
且此时n/2^i == 2
=3n/2-2 < 2(n-1)
1、如果n==1,则mid = (A[0]+B[0])/2
2、如果n>1,对A求中位数midA,对B求中位数midB
如果midA == midB,则最终的中位数为midA;
如果midA < midB, 则求A[ceil(n/2)....n]和B[1...ceil(n/2)]这两个数组的中位数T(n+1)
如果midA > midB,则求A[1...ceil(n/2)]和B[ceil(n/2)...n]这两个数组的中位数
递归方程:
T(2n) = 1 n==1;
T(2n) = T(n+1) +1 n>1
下面证T(n) = O(logn)
T(1)满足,设 m < 2n 时满足T(m) = O(logm),对 m = n+1,也满足
∴ T(n+1) <= clog(n+1)
∴ T(2n) <= clog(n+1) +1
<= clog(2n/(4/3)) +1 = clog(2n) -clog(4/3)+1
当-clog(4/3)+1 <= 0 时
<= clog(2n)
由数学归纳法,T(n) = o(logn)
(1)算法:
分治法,计算A[1...mid]的最大连续子数组A1[],再计算A[mid+1....n]的最大连续子数组A2[]。
然后计算包含A[mid]和A[mid+1]的最大子数组,即找到形如A[i......mid]和A[mid+1...j]的最大连续数组,再将其合并
(2)伪代码:
FIND-CROSS-MAX(A,low,high,mid)
left-sum = -∞
sum = 0
for i = mid downto low
sum = sum +A[i]
if sum > left-sum then
left-sum = sum
left-max = i
right-sum = -∞
sum = 0
for i = mid+1 to high
sum = sum + A[i]
if sum > right-sum then
right-sum = sum
right-max = i
return left-max,right-max,left-sum + right-sum
FIND-MAX(A,low,high)
if high == low then
return(low,high,A[low])
mid = (high - low +1 ) / 2
(left-low,left-high,left-sum) = FIND-MAX(A,low,mid)
(right-low,right-high,right-sum) = FIND-MAX(A,mid+1,high)
(mid-low,mid-high,mid-sum) = FIND-CROSS-MAX(A,low,hign,mid)
max-sum = MAX(left-sum,right-sum,mid-sum)
if max-sum == left-sum then return(left-low,left-high,left-sum)
if max-sum == mid-sum then return(mid-low,mid-high,mid-sum)
if max-sum == right-sum then return(right-low,right-high,right-sum)
递归方程:
T(n) = 1 n==1
T(n) = 2T(n/2) + O(n)
由master定理
T(n) = O(nlogn)
每3个一组,共n/3组,每组比较3次。
类比二路归并。
即3叉树倒过来。
T(n) = 0 n==1
T(n) = 1 n==2
T(n) = 3 n ==3
T(n) = 3T(n/3) + O(n) -------最后一层
T(n) = O(nlogn)
将数组分成两组,
前一半A[1:n/2],后一半A[n/2+1:n]分别求逆序对;
然后找前一半和后一半组成的逆序对。
在每次找逆序对时,将元素大小排序,得到新的B[1:n/2],C[1:n/2+1]
每次分别取前一半,后一半最小值B【1】,C【1】.
如果B【1】C【1】,则取C的下一个数C【2】和B【1】进行比较,以此类推。
T(n)= O(1),n=1,2
T(n)= 2T(n/2)+O(n)
T(n)=O(nlogn)