算法7--数组查找

1.长度为n的数组,元素大小为0-n-1,有些数字重复,找出任意一个重复数字。例如{2, 3,  1,0, 2, 5, 3} 对应输出2或3.

        由于数字长度为n,数字大小为0到n-1,可以将数字i放置在数组中i位置,若数组中i位置上数字已经是i,则说明i数字重复了,否则则进行交换,将数字i放置在数组中i位置。

public static int findNum(int[] arr){
		//遍历一遍将arr[i]放在索引为arr[i]位置上,当相等时说明数字重复,不相等则进行交换。
		for(int i=0; i<arr.length; i++){
			if(arr[i]==arr[arr[i]]){
				return arr[i];
			}else{
				int m = arr[arr[i]];
				arr[arr[i]] = arr[i];
				arr[i] = m;
			}
		}
		return -1;
	}

2.不修改数组找出重复的数字,长度为n+1,数字范围在1-n之间,找出数组中重复的任意数字,不能修改数组。

1-n范围内数字有n+1个,说明某个数字重复了。取1-n的中间值m,分为1--m和m+1--n,统计数组中在1--m中元素个数,若大于m,则说明该数字在1--m中,否则在m+1--n中。类似于二分查找,终止条件是,lo==hi并且在这个区间里面的数字个数大于1,说明找到了重复值。

public static int findNum2(int[] arr){
		int lo = 1;
		int hi = arr.length-1;
		while(lo <= hi){
			int mid = (lo + hi) >> 1;
		    int leftNum = count(arr, lo, mid);
		    System.out.println("lo = " + lo + " mid = " + mid + " left num = " + leftNum);
		    if(lo == hi){
		    	if(leftNum > 1) return lo;
		    	else break;
		    }
		    if(leftNum > mid-lo+1)
		    	hi = mid;
		    else
		    	lo = mid + 1;
		}
		return -1;
	}
	
	public static int count(int[] arr, int lo, int hi){
		int num = 0;
		for(int i=0; i<arr.length; i++){
			if(arr[i]>=lo && arr[i]<=hi)
				num++;
		}
		return num;
	}

3.二维数组的查找

二维数组从左到右递增  从上到下递增  查找是否存在某数。

以右上顶点为基准,若小于目标数,则下移,若大于目标数,则上移。

若数组无序,可以先排个序考虑一下,若数组有序,可以考虑二分法等查找方式

public static boolean findNum3(int[][] arr, int num){
		int m = arr.length;
		int n = arr[0].length;
		while(m>=0 && n>=0){
			if(arr[m][n]==num) return true;
			else if(arr[m][n]>num) n--;
			else m--;
		}
		return false;
	}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值