题目描述
现给定一个含有n个元素的数组,请随机获取其中的m个元素(不能重复获取)。
算法描述
首先,随机获取元素,可以使用rand() % 数组长度;
其次,要保证元素的不重复获取,只需将获取的元素从原数组中移除即可,但是每次都进行删除操作,需要频繁的移动数组元素,其复杂度很高;现在,我们换一种思路,将获取的元素与原数组最后的元素进行交换,再将数组的长度减一,那么就可以做到O(1)复杂度将其移除;详见下图:
此算法的时间复杂度为O(n),其只与要获取的m个数有关,在n和m相差非常悬殊的时候,效率非常高。
程序源码
// // main.m // RandSelect //// Copyright (c) 2013年 tencent. All rights reserved. // #import <Foundation/Foundation.h> #define MAXNUMBER 200 #define MAXARRAYCOUNT 10 /* 从一个随机数组中挑选一个数,不能有重复 1. 随机生成一个数组 3,33,675,7657,2345,5767,34564,3453 2. 挑选完了一个数则将其调换到最后去,或将其删除,如果不允许修改原始数组,则调换到最后去 3. 输出数组 */ void print(int *array ,int count) { for (int i=0; i<count; i++) { printf("%d ",array[i]); } printf(" "); } void swap(int array[],int length,int index) { int temp=array[index]; array[index]=array[length-1]; array[length-1]=temp; } //下面假设不允许修改原始数组,输出已经挑选好了的数组 int *selectFromArray(int *array,int count) { int *resultAry=new int[count]; //如果需要不动原数组则需要复制一份 for (int i=0; i<count; i++) { resultAry[i]=array[i]; // printf("%d ",resultAry[i]); } //开始算法 for (int i=0; i<count; i++) { int remainLength=MAXARRAYCOUNT-i; int tempIndx=rand()%remainLength; swap(resultAry,remainLength,tempIndx); } return resultAry; } int main(int argc, const char * argv[]) { @autoreleasepool { // insert code here... int *array=new int(MAXARRAYCOUNT); for (int i=0; i<MAXARRAYCOUNT; i++) { array[i]=rand()%MAXNUMBER; } print(array,MAXARRAYCOUNT); int *arrayb=selectFromArray(array, MAXARRAYCOUNT); print(arrayb, MAXARRAYCOUNT); } return 0; }