算法——假硬币

介绍

假如我有10个硬币,已知其中一个硬币是假硬币,假硬币比真硬币要轻一些

请问我如何用最少的方法找出这个假硬币


分析

用语言描述不直观,我们用计算机语言来看一遍
有一个数组,它的长度为10,其中的元素都是1,但有一个0,如下

{1,0,1,1,1,1,1,1,1,1}

用最快的方法找出0的索引


想在数组中最快获得指定元素的索引,最好的算法就是

二分

这里可能有人不知道什么是二分,引入二分的概念

在计算机科学中,二分查找算法(英语:binary search algorithm),也称折半搜索算法(英语:half-interval search algorithm)[1]、对数搜索算法(英语:logarithmic search algorithm)[2],是一种在有序数组中查找某一特定元素的搜索算法。搜索过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜索过程结束;如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间元素开始比较。如果在某一步骤数组为空,则代表找不到。这种搜索算法每一次比较都使搜索范围缩小一半。
摘自:维基百科

可能会有些看不懂,简单介绍一下

我有一个有序数组,我想从中找出某个元素。我首先从中间开始找,如果中间的正好是我想要找的,我就返回中间的索引。如果我要找的元素小于中间的元素,就在左侧数组的中间查找,大于中间元素,就从右侧数组中间查找。以此类推。这样,就可以用最快的次数找出所需元素的索引

用实例说话

static int BinarySearch(int[] arr,int n) {
		int low=0;
		int high=arr.length;
		while (low<high) {
			int mid=(low+high)/2;
			if (arr[mid]==n) return mid;
			else if (arr[mid]<n) low=mid+1;
			else high=mid;
		}
		return -1;
	}

这里用的是java代码,我相信聪明的你一定能看懂


接下来回头看我们的需求。我们想要在一堆 1中找一个 0,并且我们的数组并不是有序的,如何进行查找呢
根据我的思路,我在中间那个不符合后,我去求左右两边的和,如果存在0,则和会小一些

定义一个求和的函数
static int getSum(int[] arr,int from,int to) {
		int sum=0;
		for (int i=from;i<=to;i++) {
			sum+=arr[i];
		}
		return sum;
	}

在定义一个求中间数的函数

static int getMid(int from,int to) {
		return from+((to-from)/2);
	}

主代码

static int getCoin(int[] arr) {
		int length=arr.length;
		int low=0;int high=length-1;
		while (low<high) {
			int mid=getMid(low, high);
			if (arr[mid]==0) return mid;
			else {
				if (getSum(arr, low, mid)<=getSum(arr, mid+1, high)) high=mid;
				else low=mid+1;
			}
		}
		return -1;
	}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值