剑指offer+面试题3-数组中重复的数字(java解答)

题目一:在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是第一个重复的数字2。
考点:

  • 对一维数组的理解及编程能力:一维数组在内存中占据连续的空间,因此我们可以根据下标定位对应元素
  • 分析问题的能力:通过具体例子找出其中规律,是解决问题的关键

题目二: 在一个长度为n+1的数组里的所有数字都在1~n的范围内,所以数组中至少有一个数字是重复的。请找出数组中任一个重复的数字,但是不能修改输入的数组。例如,如果输入长度为8的数组{2,3,5,4,3,2,6,7},那么对应的输出是重复的数字2或3。

考点:

  • 对一维数组的理解及编程
  • 对二分查找算法的正确理解
  • 沟通能力:了解需求,针对性解决问题

已经在github上进行了更新

package offer;

public class T01_FindDuplication{
	
	//找出数组中重复的数字
	public boolean duplicate(int[] numbers) {
		if(numbers==null||numbers.length<=0)
			return false;
		int length=numbers.length;
		for(int i =0;i<length;++i) {
			if (numbers[i]<0||numbers[i]>length-1)
				return false;
		}
		for(int i=0;i<length;++i)
		{
			while(numbers[i]!=i)
			{
				if(numbers[i]==numbers[numbers[i]])
				{
					int duplication=numbers[i];
					System.out.println(duplication);
					return true;
				}
				//swap numbers[i] and numbers[numbers[i]]
				int temp=numbers[i];
				numbers[i]=numbers[temp];
				numbers[temp]=temp;
				
			}
		}
		return false;
	}
	
	
	//不修改数组,找出重复数字
	public int getDuplicate(int[] numbers)
	{
		//判定数组是否为空
		if(numbers==null||numbers.length<=0)
		{
			System.out.println("数组输入无效!");
			return -1;
		}
		
		//判定数组是否越界
		int length=numbers.length;
		for (int a:numbers) {
			if(a<0||a>length-1) {
				System.out.println("数字大小超出范围!");
				return -1;
			}
		}
		
		//二分法查找有无重复数字
		int start=1;
		int end=length-1;
		while(end>=start)
		{
			int middle=((end-start)>>1)+start;
			int count=countRange(numbers,length,start,middle);
			if(end==start)
			{
				if(count>1)
					return start;
				else
					break;
			}
			if(count>(middle-start+1))
				end=middle;
			else
				start=middle+1;
		}
		System.out.println("数组中无重复数字!");
		return -1;
	}
	//统计区间里数字的数目
	public int countRange(int[] numbers,int length,int start,int end)
	{
		if(numbers==null)
			return 0;
		int count=0;
		for(int i=0;i<length;i++) {
			if(numbers[i]>=start&&numbers[i]<=end)
				++count;
		}
		return count;
	}
	
	//===============================测试代码==================================
	
	/*数组为null*/
	public void test1() {
		System.out.println("test1:");
		int[] a=null;
		boolean res=duplicate(a);
		System.out.println("有无重复数字:"+res);
		int dup=getDuplicate(a);
		if (dup>=0)
			System.out.println("重复数字为:"+dup);
	}

	/*数组无重复数字*/
	public void test2() {
		System.out.println("test2:");
		int[] a= {0,1,2,3};
		boolean res=duplicate(a);
		System.out.println("有无重复数字:"+res);
		int dup=getDuplicate(a);
		if(dup>=0)
			System.out.println("重复数字为:"+dup);
		
	}
	
	/*数组数字越界*/
	public void test3() {
		System.out.println("test3:");
		int[] a= {1,2,3,4};
		boolean res=duplicate(a);
		System.out.println("有无重复数字:"+res);
		int dup=getDuplicate(a);
		if(dup>=0)
			System.out.println("重复数字为:"+dup);
	}
	
	/*数组带重复数字*/
	public void test4() {
		System.out.println("test4");
		int[] a= {1,2,3,2,4};
		boolean res=duplicate(a);
		System.out.println("有无重复数字:"+res);
		int dup=getDuplicate(a);
		if(dup>=0)
			System.out.println("重复数字为:"+dup);
	}
}

主函数调用

import offer.T01_FindDuplication;

public class Solution{
	
	public static void main(String[] args) {
		T01_FindDuplication test=new T01_FindDuplication();
		test.test4();
	}
}

具体文件目录

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值