成功算法的“必经之路”:细节的修改

前言:

在算法设计中,你肯定遇到过这样的问题,明明我就是按照大体思路来进行设计的,可为什么 结果就是不对呢?你抓狂,我也抓狂。

这其实就关乎算法细节上的问题了。在这里,细节从未如此重要,程序世界仅仅一个 看似微不足道的错误,就能导致算法的彻底失效!

今天我们从具体实例出发、复现你抓狂的情景,来带你探讨算法细节设计工作中的基本方法——从具体到抽象。

论述:

我们面临的绝大多数的算法都是对数据加工处理的算法,这很好笑,这当然是,因为计算机能做之一就是对数据的运算。我们来看这道算法的运算,相信大家不陌生,是二分查找算法。

给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。

算法的基本思想是将待查找区间分为两部分,判断中间元素与目标值的关系,以决定是取左半区间还是右半区间继续查找。然后我对着电脑一顿猛巧,把这个思想逻辑用代码的形式实现成了这样

我可能遇到这样中情景:我搞不清楚 while left ? right: 这个循环条件到底是 < ?,还是 <=

def binary_search(arr, target):
    left, right = 0, len(arr) - 1
    while left ? right:  # 循环条件待确定
        mid = left + (right - left) // 2
        if arr[mid] < target:
            left = mid + 1
        elif arr[mid] > target:
            right = mid - 1
        else:
            return mid
    return -1
//**********附上C语言版本***********
int binary_search(int arr[], int n, int target) {
    int left = 0, right = n - 1;
    while (left ? right) {
        int mid = left + (right - left) / 2;
        if (arr[mid] < target) {
            left = mid + 1;
        } else if (arr[mid] > target) {
            right = mid - 1;
        } else {
            return mid;
        }
    }
    return -1;
}

唤起你记忆了吧,其实这种类似的情况我们也发生过,这时候该怎么办?那就是把抽象的数据处理过程,转变为具体的数据处理过程,在具体的数据中帮助我们细节的设计。具体的数据我们更容易把握,能容易监控数据处理的过程,发现其中的问题。

我不确定那就假设为“<”,具体数据我设简单点arr = [1, 2, 3, 4, 5],目标值target = 5。那么算法的执行过程是这样的:

  1. 初始时,left = 0right = 4
  2. 第一次循环,mid = 2arr[mid] = 3,小于target,因此left变为mid + 1,即left = 3
  3. 第二次循环,left = 3right = 4mid = 3arr[mid] = 4,仍然小于targetleft再次变为mid + 1,即left = 4
  4. 如果此时循环条件是left < right,那么循环将结束,算法返回-1,这显然是错误的,因为target实际上存在于数组中。

我们分析当target是数组中的最后一个元素时,如果使用left < right作为循环条件,算法将提前退出循环。因此,正确的循环条件应该是left <= right,这样即使leftright相等,也会再执行一次循环,确保不会错过目标值。于是我们找到了符合这个具体数据的算法,它是恰巧的吗?我们在回归抽象的在模拟这个算法的执行发现是通用的,我们找到了适用于通用数据的算法。

这样我们解决了这个算法问题。在这次讲述中我并不想让大家过多关注二分查找算法,这仅是一个例子,在这个例子中我们通过带入具体的数据最后找到了正确的算法。不光这一个应用场景,我想告诉大家,在我们面对复杂的算法设计任务时,我们可能会呈现出“稀里糊涂”的状态,遇到不确定的算法细节设计的时候,我们都可以带入具体的数据来帮助我们理清执行过程,找到你最后期望的成功算法

~~~~~~

以上就是我本篇想讲的所有内容了,如果这篇文章对你有价值的话,还请点个赞,你的支持对我非常重要!

我是阿航,一位胆大包天、梦想成为大牛的学生~ 

我们下篇文章接着聊

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值