数组下标的巧用(约瑟夫环等)
来源:互联网 发布:网络商业模式 编辑:程序博客网 时间:2024/05/23 01:18
数组下标的巧用(约瑟夫环等)
最近在牛客网看到华为的笔试题,如下一题,不难,但觉得遇到好多可以巧用数组下标来存储数据的案例,觉得可以列在一起分享一下。
题1:
明明想在学校中请一些同学一起做一项问卷调查,为了实验的客观性,他先用计算机生成了N个1到1000之间的随机整数(N≤1000),对于其中重复的数字,只保留一个,把其余相同的数去掉,不同的数对应着不同的学生的学号。然后再把这些数从小到大排序,按照排好的顺序去找同学做调查。请你协助明明完成“去重”与“排序”的工作。
Input Param
n 输入随机数的个数
inputArray n个随机整数组成的数组
Return Value
OutputArray 输出处理后的随机整数
因为输入的数的个数不限,然后需要去重,再排序。所以大家的下意识常规做法:先排序,这样重复的在一起,然后遍历去重就好了。
低效常规做法:
#include<stdio.h>int main(){int n,a[10000],i,j,k,temp;while(scanf("%d",&n)!=EOF){for(i=0;i<n;i++)scanf("%d",&a[i]);for(i=0;i<n;i++){for(j=i+1;j<n;j++){if(a[i]==a[j]){for(k=j+1;k<n;k++)a[k-1]=a[k];n--;j--;}}}for(i=0;i<n-1;i++){for(j=0;j<n-1-i;j++){if(a[j]>a[j+1]){temp=a[j];a[j]=a[j+1];a[j+1]=temp;}}}for(i=0;i<n;i++)printf("%d\n",a[i]);}}
但海量数据排序,怎么也逃不了两层嵌套循环,效率很低。于是可以这么想,因为输入的数不超过1000,所以可以定义一个1000长度的一维数组,下标可以作为输入的数,如果输入,对应下标的数据置1,标记为已存在,这样下标默认排序了,同时也去重了。下标的妙用如下:
//1-1000随机数,去重,排序(这里只要输入数的范围不是特别大,都可以这么用,输入的个数无所谓)
#include <iostream>using namespace std;int main() { int N, n; while (cin >> N) { int a[1001] = { 0 }; while (N--) { cin>> n; a[n]= 1; } for (int i = 0; i < 1001;i++) if (a[i]) cout<< i << endl; } return 0;}
同样的用法,我想起之前写约瑟夫环的问题:
已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。
之前,自己用的循环链表来写,每次不停的去数数,然后遍历,删除节点,再数数,直至所有结点全部剔完。后来用这种方法,数组下标标记法。踢出去置0或者置1标记下就好。效率高了很多。因为数组的查找效率是O(1
class Solution { public: int LastRemaining_Solution(unsigned int n, unsigned int m) { if(m==0||n==0) return -1; struct Lnode{ int data; Lnode* next; }; int len = sizeof(struct Lnode); unsigned int i=1; struct Lnode* head = (struct Lnode*)malloc(len); head->data=0; //因为需要一个圈,这里是头结点(也就是带数据的),不是头指针。 head->next=NULL; struct Lnode* cur = head; while(i<n){ struct Lnode* p = (struct Lnode*)malloc(len); p->data=i; p->next=NULL; cur->next = p; cur = p ; i++; } cur->next = head; //形成循环链表,首尾相连了 Lnode* q=head; Lnode* pre; //为下面删除结点定义一个前驱 while(n>1){ //删除数到的结点 i=0; while(i++<m-1){ //遍历到第m-1个结点 pre=q; q=q->next; } pre->next=q->next; free(q); q=pre->next; --n; } return (q->data); } };
后来用数组改进:
#include<iostream>#include<cstdlib>#include<cstring>#define MAX 101using namespace std;int main(){ boola[MAX]; intn,m; cin>>n>>m; memset(a,0,sizeof(int)*n); //memset(a,false,sizeof(int)*n); // for(int i=1;i<=n;++i)a[i]=false; intout=0,t=0,s=0; do { ++t; if(t==n+1) t=1; if(false==a[t]) ++s; if(s==m) { a[t]=true; ++out; s=0; cout<<t<<" "; } }while(out!=n); system("pause"); return 0;}数组下标用来存储数据,而数组元素存其标志,可以有很多妙用。。
- 数组下标的巧用(约瑟夫环等)
- 约瑟夫环:每隔两个循环删除数组元素,求最后删除者的下标问题
- 巧用数组实现约瑟夫环 (一道有意思的题目, 一个很巧的解法)
- 约瑟夫环的数组实现
- 约瑟夫环的数组实现
- C/C++面试之算法系列--约瑟夫环:每隔两个循环删除数组元素,求最后删除者的下标问题
- 用枚举定义有意义的数组下标
- 用枚举定义有意义的数组下标
- 用枚举定义有意义的数组下标
- 用枚举定义有意义的数组下标
- 用枚举定义有意义的数组下标
- 用枚举定义有意义的数组下标
- Vector用数组下标访问的条件
- 数组的下标应用
- 数组下标的本质
- VBScript的数组下标
- 数组下标的排序
- 坏的数组下标
- SqlServer查询分组后每个分组的第N条数据
- tensorflow的简单使用、保存、加载
- liunx安装jdk
- 【Clone】复制克隆
- Enhancement of SSD by concatenating feature maps for object detection笔记
- 数组下标的巧用(约瑟夫环等)
- Spring中IoC初识
- 等值首尾和
- js语法深入三:对js函数的理解及深入讨论
- 19 个 JavaScript 常用的简写技术
- SQL最便捷的列转行语句
- 微信开发 分享功能 php,自定义微信分享功能
- SPOJ
- 算术右移(>>)与逻辑右移(>>>)有什么区别