关于数组的一些小算法

1.已知两个有序数组A,B,将它们合并为一个有序数组。利用到的是归并算法的思想。


int* combine(int a[],int n1,int b[],int n2)
{
int i = 0,j = 0,k = 0;
int *c = new int[n1+n2];
while(i<n1&&j<n2) //依次比较a,b数组当前元素,将小的元素放前面,下标后移
{
if(a[i]<=b[j])
c[k++] = a[i++];
else
c[k++] = b[j++];
}
while(i<n1) //将剩余元素拷贝过去
{
c[k++] = a[i++];
}
while(j<n2)
{
c[k++] = b[j++];
}
return c;
}

2.删除数组中重复元素


void delete_same(int a[],int &n)
{
int i,j;
if(n==0)
return;
else
{
for(i = 0,j = 1;j<n;j++)
{
if(a[i]<a[j])
a[++i] = a[j];
}
}
n = i+1;
}

3.已知一个数组A,要求将数组元素循环左移p位。如一个数组A{a1,a2,a3,a4,a5}循环左移3位变成A{a4,a5,a1,a2,a3}.
一个思路是利用辅助数组,时间复杂度为O(n),空间复杂度为O(p)。还有一种高效的策略是将A的前P个元素逆置,再将后n-p个元素逆置,最后逆置整个数组。时间复杂度为O(n),空间复杂度为O(1)


void reverseA(int a[],int b,int e) //将b-e之间的数组逆序
{
int mid = (b+e)/2;
for(int i = b;i < mid;i++)
{
int t = a[i];
a[i] = a[e-(i-b)];
a[e-(i-b)] = t;
}
}

void moveA(int a[],int n,int p)
{
reverseA(a, 0, p-1);
reverseA(a, p, n-1);
reverseA(a, 0, n-1);
}

4.两个有序序列,查找这两个有序序列的中位数。


int findmid(int a[],int b[],int n)
{
int s1 = 0,e1 = n-1;
int s2 = 0,e2 = n-1;
while(s1 != e1&&s2 != e2){
int m1 = (s1+e1)/2;
int m2 = (s2+e2)/2;
if(a[m1]==b[m2])
return a[m1];
else if(a[m1]<b[m2]){
if((s1+d1)%2==0)
{
s1 = m1;
e2 = m2;
}
else
{
s1 = m1+1;
e2 = m2;
}
}
else
{
if((s2+d2)%2==0)
{
e1 = m1;
s2 = m2;
}
else
{
e1 = m1;
s2 = m2+1;
}
}
}
return a[s1]<b[s2]?a[s1]:b[s2];
}

关于数组的一些小算法,布布扣,bubuko.com

时间: 2024-12-31 06:18:21

关于数组的一些小算法的相关文章

小算法:合并两个有序数组,合并之后仍然有序

1 /** 2 * 合并两个有序数组,合并后仍然有序 3 * @param a 要合并的数组A 4 * @param b 要合并的数组B 5 * @param c 合并后的数组C 6 */ 7 public static void merge(int a[] ,int b[],int c[]){ 8 int lengthA = a.length; 9 int lengthB = b.length; 10 11 int indexA = 0; 12 int indexB = 0; 13 int i

每天一个小算法(2)----合并两个有序链表

每天一个小算法还是有点没时间,尽量抽出时间写一写. 今天是合并有序的链表,对单链表有点忘了,尤其是指针指来指去的,有点晕,幸好基础还算好,想了想还是能想回来. 代码使用随机数函数生成一个链表,然后对链表排序,最后合并链表并打印,删除链表的函数于算法无关紧要,所以未实现^_^. 在Linux/g++下编译运行成功. 合并思路:和合并数组有些类同,比较两个节点的元素大小然后将小的摘下来尾插到链表bList中,然后指针指向下一个节点,最后直接把非空的链表合并到bList的末尾. 1 #include

log(n)时间内找出数组第i小的数字

参考算法导论9.2 R_Select(int *a,int p,int r,int i){ if(p==r) return a[p]; int q=partition(a,p,r); int k=q-p; if(i==k) return a[q]; else if(i<k) return R_Select(a,p,q-1,i); else return R_Select(a,q+1,r,i-k); } log(n)时间内找出数组第i小的数字

java每日小算法(27)

/* [程序27]  题目:求100之内的素数    */ package test; import java.util.Scanner; public class test { public static boolean prime(int number) { boolean flag = true; int mid = (int)Math.sqrt(number); for(int i = 2; i< mid+1; i++) { if(number % i == 0) { flag = fa

关于js数组的一道小考题

网上看到的一道关于js数组的小考题,借此学习练习一下,也是拿来作为博客开篇之作吧! 题目如下: 给定一个随机数组,数组可能包含数组(也就是说数组元素可能为数组).要求用js实现一个函数,返回该数组中所有元素,重复的要求去掉.例如:数组[2,3,[4,6,[3,8]],12,10],返回结果为:[2,3,4,6,8,12,10]. 我的答案如下:(额外增加了排序) 1 var arr = [2,3,[4,6,[3,8,[15,16,[17,18,[1,2,3,[19,20]]]]],[13,14]

java每日小算法(4)

[程序4] 题目:将一个正整数分解质因数.例如:输入90,打印出90=2*3*3*5. 程序分析:对n进行分解质因数,应先找到一个最小的质数k,然后按下述步骤完成: (1)如果这个质数恰等于n,则说明分解质因数的过程已经结束,打印出即可. (2)如果n<>k,但n能被k整除,则应打印出k的值,并用n除以k的商,作为新的正整数你n,重复执行第一步. (3)如果n不能被k整除,则用k+1作为k的值,重复执行第一步. package test; import java.util.ArrayList;

特殊的日子(2015年5月1日劳动节)纪念回归和新的征程,用LRU和LFU两个小算法原理和区别来抛砖引玉

很久没有写过新的博客了,原因有很多,冠冕堂皇的理由就是工作忙,生活忙,各种累,直白一点其实就是变懒了,所以没有写. 在沉寂了这么长一段时间过后,终于又要重新出发了,对于自己当前的状态,觉得首先要有所沉淀,然后就是要放空自己,唯有放空自己方能继续进步. 以后一段时间更新的博客内容主体是与Android Framework相关的疑难问题分析.机制实现的原理.源代码调用分析,然后伴有一些常用的小算法,语言特性,程序原理等. 今天就先介绍LRU和LFU这两个在Android的Framework以及App

循环圈小算法

小算法循环圈的公式:(n+1) % (maxN+1) 比如实现0到3的循环 0+1 %4 = 1 1+1 %4 = 2 2+1 %4 = 3 3+1 %4 = 0 比如实现1到3的循环 1+1 %4 = 2 2+1 %4 = 3 3+1 %4 = 1

大数据处理时的一种BitMap小算法

一种大数据外部排序(内存无法加载所有排序元素).去除重复元素.快速找到随机被删除元素的BitMap小算法,核心思想即通过将一个数作为下标(index)来索引一个bit表示一个数是否存在,排序时的时间复杂度为O(N),需要的额外空间的复杂度O(N/8),支持整个int范围(正负数都支持)的算法示例如下: char BitMask[] = {0x80 , 0x40 , 0x20 , 0x10 , 0x8 , 0x4 , 0x2 , 0x1}; int WriteNumberBitToByte(cha