我同学笔试的时候出的。我没做出来。
给一个数组a[n] n可以为任意奇数,但是数组中的数都是0-99之间的数,现在要求最多只遍历数组一次,找出数组中大小处于数组中间的那个数。
注意:该中间的数可能在数组中不止出现一次
比如a[n]={2,8,88,33,66,54,54,99,88}; 排序后是{2,8,33,54,54,66,88,88,99},那么结果就使索引为4的那个数 即54
给一个数组a[n] n可以为任意奇数,但是数组中的数都是0-99之间的数,现在要求最多只遍历数组一次,找出数组中大小处于数组中间的那个数。
注意:该中间的数可能在数组中不止出现一次
比如a[n]={2,8,88,33,66,54,54,99,88}; 排序后是{2,8,33,54,54,66,88,88,99},那么结果就使索引为4的那个数 即54
解决方案 »
- 求助高手:有没有不使用多线程使代码等待一定时间再执行的方法?
- 贴3个帖子了,也没人回,谁来帮帮我哦。。。。。。。。
- 用JBuilder2006如何将工程或者类做成.jar文件啊?
- 一个GUI的简单问题
- 请问,这些是什么古怪的日期格式?(JAVA+DB2)
- ■■简单问题,调用System.currentTimeMillis(),得到结果为1048061083957是如何得到的?■■
- 为什么我设置JPanel的Bounds后,不能看到,而抛出异常?请帮忙,谢谢!
- 为什么Store的connect这么慢?有没有什么好办法?
- 在JBuilder for winnt中如何去掉输入法的bug?
- 介个咋弄,我好像自己不行~
- 如何通过异常获取异常的具体ORa_XXXX值?
- 判断是否是叶节点的isleaf()函数具体实现方式?
首先对数组a[n]遍历一次取 a[(n/2)+1]的值,然后用 a[n/2]和a[(n/2)+1]进行比较,相等继续用a[(n/2)]和a[(n/2)-1]比较,直到不相等则终止比较输出结果。
然后数列求和 取平均数
比较a[i-1],a[i]与平均数的差 确定遍历方向
差最小的即是
public class Test23 {
public static void main(String[] args) {
int[] an = {2, 8, 88, 33, 66, 54, 54, 99, 88};
System.out.println(mid(an));
}
public static int mid(int[] an) {
if(an.length % 2 == 0) { //数组长度不是奇数,不考虑了,下面是一次取两个,这里是防止出异常。
return 0;
} else if(an.length == 1) { //只有一个数。
return an[0];
}
int m = an[0];
int l = 0;
int h = 0;
int a = an[1];
int b = an[2];
if(an[1] > an[2]) {
a = an[2];
b = an[1];
} else {
a = an[1];
b = an[2];
}
//处理前三个数
if(a >= m) {
l = m;
m = a;
h = b;
} else if(b <= m) {
h = m;
m = b;
l = a;
} else {
l = a;
h = b;
}
//两个两个取出并处理
for(int i = 3; i < an.length; i += 2) {
if(an[i] > an[i+1]) {
a = an[i+1];
b = an[i];
} else {
a = an[i];
b = an[i+1];
}
if(a >= m ) {
l = m;
m = a < h ? a : h;
h = b < h ? b : h;
} else if(b <= m) {
h = m;
m = b > l ? b : l;
l = a > l ? a : l;
} else {
l = a > l ? a : l;
h = b < h ? b : h;
}
}
return m;
}
}代码只写了方法,没写测试,测试自己写吧,随机生成199个0-99的数(必有重复了)。然后调用这个方法
public class Test23 {
public static void main(String[] args) {
int[] an = {2, 8, 88, 33, 66, 54, 54, 99, 88};
System.out.println(mid(an));
}
public static int mid(int[] an) {
if(an.length % 2 == 0) { //数组长度不是奇数,不考虑了,下面是一次取两个,这里是防止出异常。
return 0;
} else if(an.length == 1) { //只有一个数。
return an[0];
}
int m = an[0];
int l = 0;
int h = 0;
int a = an[1];
int b = an[2];
if(an[1] > an[2]) {
a = an[2];
b = an[1];
} else {
a = an[1];
b = an[2];
}
//处理前三个数
if(a >= m) {
l = m;
m = a;
h = b;
} else if(b <= m) {
h = m;
m = b;
l = a;
} else {
l = a;
h = b;
}
//两个两个取出并处理
for(int i = 3; i < an.length; i += 2) {
if(an[i] > an[i+1]) {
a = an[i+1];
b = an[i];
} else {
a = an[i];
b = an[i+1];
}
if(a >= m ) {
l = m;
m = a < h ? a : h;
h = b < h ? b : (a < h ? h : a);
} else if(b <= m) {
h = m;
m = b > l ? b : l;
l = a > l ? a : (b > l ? l : b);
} else {
l = a > l ? a : l;
h = b < h ? b : h;
}
}
return m;
}
}
public static int medInArray(int[] arr) {
int med = arr[arr.length/2+1];
int sum = arr[arr.length/2+1];
for(int i=0; i<arr.length; i++) {
if(i < arr.length/2) {
sum += arr[i] + arr[arr.length-1-i];
} else {
if(Math.abs(arr[i]*arr.length - sum) < Math.abs(med*arr.length - sum)) {
med = arr[i];
}
if(Math.abs(arr[arr.length-1-i]*arr.length - sum) < Math.abs(med*arr.length - sum)) {
med = arr[arr.length-1-i];
}
}
}
return med;
}
应该算是遍历一次吧,没有测试
a[n]={2,8,88,33,66,54,54,99,88};
b[n]=Arrays.sort(a[n].clone())
int result=b[(n-1)/2]
int[] b =new int[100];
Vector<Integer> vector = new Vector<Integer>();
//遍历数组
for(int j = 0;j<array.length;j++ ){
//排序后是{2,8,33,54,54,66,88,88,99},那么结果就使索引为4的那个数
//是靠后的那个数所以可以覆盖b[array[i]];
//
b[array[j]]=j;
}
for(int i =0;i<b.length;i++){
if(0!=b[i]){
vector.addElement(b[i]);
}
}
// 给一个数组a[n] n可以为任意奇数,
return vector.elementAt(vector.size()/2);
}
public static void main(String[] args) {
int b[]= {2,8,88,33,66,54,54,99,88};
//int b[]= {2,8,88,33,66,54,54,99,88,34,43};
System.out.println(getMidIndex(b));
}
int[] b =new int[100];
public class test { public static int a(int[] arr){
int rs=0;
for(int i=0;i<arr.length;i++){
for(int j=0;j<arr.length-1;j++){
if(arr[j]>arr[j+1]){
arr[j]=arr[j]^arr[j+1];
arr[j+1]=arr[j+1]^arr[j];
arr[j]=arr[j]^arr[j+1];
}
}
}
rs=arr[(arr.length-1)/2];
return rs;
}
public static void main(String[] args) {
int arr[]={2,8,88,33,66,54,54,99,88};
System.out.println(test.a(arr));
}}
不对请大家纠正哈 呵呵
不好意思没仔细测试
有个 小BUG基本思想是 采用桶装排序 public static int getMidIndex(int[] array){
// 给一个数组a[n] n可以为任意奇数,但是数组中的数都是0-99之间的数,
int[] b =new int[100];
Vector<Integer> vector = new Vector<Integer>();
//遍历数组
for(int j = 0;j<array.length;j++ ){
//排序后是{2,8,33,54,54,54,54,66,88,88,99},那么结果就使索引为4的那个数
//是靠后的那个数所以可以覆盖b[array[i]];
//
b[array[j]]=j;
}
for(int i =0;i<b.length;i++){
if(0!=b[i]){
vector.addElement(b[i]);
}
}
//是靠后的那个数所以可以覆盖b[array[i]];这里修改下 return vector.size()%2==0?vector.elementAt(vector.size()/2-1):vector.elementAt(vector.size()/2);
}
public static void main(String[] args) {
int b[]= {2,8,88,33,66,54,54,99,88};
//int b[]= {2,8,88,33,66,54,54,99,88,34,43};
System.out.println(getMidIndex(b));
}
这理还是有错误
桶中的数字
只有偶数种值(0-99除掉重复的)即(24,43,56,78)不好判断中间的两个数字43 出现多(return vector.elementAt(vector.size()/2-1))还是65出现多(vector.elementAt(vector.size()/2):),谁出现的次数多应该返回
搞了半天了看来考虑还是不够全面啊 谢谢26楼的提醒
public static int getMidIndex(int[] array){
int[] b =new int[100];
int[] bcopy = new int[100];
Vector<Integer> vector = new Vector<Integer>();
//标志位
Vector<Integer> vectorcopy = new Vector<Integer>();
//遍历数组
for(int j = 0;j<array.length;j++ ){
//排序后是{2,8,33,54,54,54,54,66,88,88,99},那么结果就使索引为4的那个数
//是靠后的那个数所以可以覆盖b[array[i]];
//证明b[array[j]]已经存在需要替换
if(b[array[j]]!=0){
bcopy[array[j]]++;
}
b[array[j]]=j;
}
for(int i =0;i<b.length;i++){
if(0!=b[i]){
vector.addElement(b[i]);
//对应的重复次数2个相同为1次
vectorcopy.addElement(bcopy[i]);
}
} int front = vector.elementAt(vector.size()/2-1);
int back = vector.elementAt(vector.size()/2);
//如果桶中的值为偶数种根据copy标志位判断取谁;
if(vector.size()%2==0){
return vectorcopy.elementAt(vector.size()/2-1)>vectorcopy.elementAt(vector.size()/2)?front:back;
}
return vector.elementAt(vector.size()/2);
}
public static void main(String[] args) {
int b[]= {2,8,88,33,66,54,54,99,88};
//int b[]= {2,8,88,33,66,54,54,99,88,34,43};
System.out.println(getMidIndex(b));
}
public static void main(String args[])
{
int a[]={2,8,88,33,66,54,54,99,88};//初始化数组
ArrayList<Integer> list = new ArrayList<Integer>();
int b[] = new int[a.length];
b[0]=a[0];
/*
* 遍历一次数组
*/
for(int i=1;i<a.length;i++)
{
int j=0;
int k = a[i];
if(!list.contains(a[i]))//排除重复的数字,不重复的数字放入list中
{
list.add(a[i]);
/*
* 将不重复的数字排序
*/
while(b[j]!=0&&j<b.length-1)
{
int k2=k;
if(b[j]>k)
{
k=b[j];
b[j]=k2;
}
if(j<b.length-1&&b[j+1]==0)
{
b[j+1]=k;
break;
}
j++;
}
}
}
System.out.println(b[list.size()/2]);//输出,排序后最中间的数。当然如果出现2个也就是不重复的是8个那么第4~5个数字应该都是中间数吧?这里只打印第4个
}
/**
* 给一个数组a[n] n可以为任意奇数,但是数组中的数都是0-99之间的数,现在要求最多只遍历数组一次,找出数组中大小处于数组中间的那个数。
*注意:该中间的数可能在数组中不止出现一次
*比如a[n]={2,8,88,33,66,54,54,99,88}; 排序后是{2,8,33,54,54,66,88,88,99},那么结果就使索引为4的那个数 即54
* @author Ydy from Wyu
*
*/
public class FindMid {
public static int find(int[] a){
int[] temp = new int[100];//既然已经限定范围是0-99,该数组已可满足要求
for(int i=0;i<a.length;i++)
{
temp[a[i]]+=1;//a[i]的值作下标,temp[i]中的值表示数i出现的次数
}
int sum=0;
for(int i=0;i<temp.length;i++){
sum+=temp[i];
if(sum>=a.length/2)//已限定输入数组是奇数个,所以判断较简单
return i;
}
return 0;
}
public static void main(String args[])
{
int[]a={5,23,7};
int[] b={2,8,88,33,66,1,1,54,54,99,88};
System.out.println(find(a));
System.out.println(find(b));
}
}
比如int[] a = {2,8,88,33,66,55,54,99,88};
不太明白,感觉题目出的有问题.
比较喜欢20楼
import java.util.Collections;
import java.util.List;public class test {
public static void main(String []args){
int []arr=new int[]{12,32,22,1,55,22,33};
List arrl=new ArrayList();
for(int i=0;i<arr.length;i++){
arrl.add(arr[i]);
}
Collections.sort(arrl);
for(int i=0;i<arrl.size();i++){
System.out.println(arrl.get(i)+" ");
}
System.out.println("此數為:"+arrl.get(arrl.size()/2));
}
}
按照这个算法,如果是数组int[] a = {1,1,1,1,1,1,1,9,20}会得出什么结果?
找出数组中“大小”处于数组中间的那个数,这个数未必就是组数中间的数吧?
应该是说数组中的一个数,它的大小排在数组中所有数的中间,并不是指它的下标。
我是这么理解的。
public static int find(int[] a){
int[] temp = new int[100];
for(int i=0;i<a.length;i++)
{
temp[a[i]]+=1;
}
int sum=0;
for(int i=0;i<temp.length;i++){
sum+=temp[i];
if(sum>=(a.length+1)/2)//这里应该是a.length+1
return i;
}
return 0;
//这个效率应该是最优的。
}
如果指定的数组能容纳队列,并有剩余的空间(即数组的元素比队列多),那么会将数组中紧接 collection 尾部的元素设置为 null。(仅 在调用者知道列表中不包含任何 null 元素时才能用此方法确定列表长度)。
排完后只要取出数组中的 (int)(n/2+1)位置上的值就0K了
public static int getMiddleNum(int []ia)
{
List arrl=new ArrayList();
for(int i=0;i <ia.length;i++){
arrl.add(String.valueOf(ia[i]));
}
Collections.sort(arrl);
int m=ia.length/2;
return Integer.parseInt(arrl.get(m+1).toString()); }
我想这样就可以了
如果指定的数组能容纳队列,并有剩余的空间(即数组的元素比队列多),那么会将数组中紧接 collection 尾部的元素设置为 null。(仅 在调用者知道列表中不包含任何 null 元素时才能用此方法确定列表长度)。
排完后只要取出数组中的 (int)(n/2+1)位置上的值就0K了
public static void main(String[] args) {
getMinNum(5);
}
public static void getMinNum(int n) {
int[] a = new int[n];
Random r = new Random();
for(int i=0;i<a.length;i++) {
a[i] = r.nextInt(99);
System.out.println(a[i]);
}
System.out.println("----------------------");
Arrays.sort(a);
for(int i=0;i<a.length;i++) {
System.out.println(a[i]);
}
System.out.println("------------------------");
System.out.println(a[(n-1)/2]);
}
}