[消失的数字] 还能用位运算解决?

来源:力扣(LeetCode)
链接:面试题 17.04. 消失的数字

题目

数组nums包含从0到n的所有整数,但其中缺了一个。请编写代码找出那个缺失的整数。你有办法在O(n)时间内完成吗?
注意:本题相对书上原题稍作改动

输入:[3,0,1]
输出:2

输入:[9,6,4,2,3,5,7,0,1]
输出:8

题目解析

首先了解题目大意:0 — n 中少了一个数字,让我们求出
我现在所能想到的,有三种方法:

  1. 哈希表,通过使用哈希表对完整的 0 — n 计数,最终得到出现次数为 0 的数;
  2. 使用二分查找,在完整的 0 — n 上进行二分查找,最终找到要求数;
  3. 使用位运算解决

接下来唠叨一下方法二与方法三:

二分查找

思想与相同,通过构造一个假想的完整的 0 — n ,并对其进行二分查找,比如二分查找的中值为4,那么我们在原数组中找小于等于4的个数,如果不含缺失数的话,应该能找到(0, 1, 2, 3, 4)五个数,但如果找到的数小于等于4个,则说明0—4中含有缺失数,则right = mid, 反之,left = mid + 1;
对这种寻找思想感兴趣的话,还可以看这篇文章用二分法解决【寻找重复数】问题

代码
class Solution {
    public int missingNumber(int[] nums) {
        //二分查找
        Arrays.sort(nums);
        int len = nums.length;
        if(len == 1){
            return nums[0] == 0 ? 1 : 0;//特殊情况,当n == 1 的时候,应包含[0, 1]
        }
        int left = 0, right = len;//左指针,右指针
        while(left < right){//循环条件
            int mid = left + (right - left) / 2;//中值
            int cnt = 0;//计数
            for(int num :nums){
                if(num <= mid){//原数组中小于等于mid的个数(正常应该有 mid+1 个)
                    cnt += 1;
                }
            }
            if(cnt <= mid){//如果不到 mid+1 个,即 <= mid
                right = mid;//则 0——mid 中有缺失
            }else{//反之
                left = mid + 1;// mid+1 —— len 有缺失
            }
        }
        return left;//返回left或right(由于循环条件此时left == right)
    }
}
位运算

这道题目如何用位运算解决呢,当我们看到这道题目的时候,发现他与只出现一次的数字(位运算java)很相似,不同的是,这道题目中有一个数出现的次数是0次,如果让每个数出现的次数都加1,那么两道题好像就一样了。
同样的,我们使用异或的特点:

相同数异或 结果为0
不同数异或 结果为1
一个数与0异或 结果为其本身。

代码
class Solution {
    public int missingNumber(int[] nums) {
        //位运算
        int len = nums.length;//数组中应含有 0——len 即 len+1 个数,少一个数,则只有 len 个数
        int m = 0, res = 0;
        for(int num : nums){//循环 len 次,0——len-1 个数
            res ^= num ^ m;
            m += 1;//用m来表示不缺失的 0——len-1 的 len 个数
        }
        return res ^ len;//记得带上第 len 个数
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 或梯度爆炸? 在深度学习中,当梯度值趋近于零,就称为梯度消失。而当梯度值变得非常大,超过了计算机能够表示的范围,就称为梯度爆炸。 因此,如果打印出的梯度值在训练过程中逐渐变小,趋近于零,就说明存在梯度消失的问题。相反,如果梯度值在训练过程中变得非常大,超过了计算机能够表示的范围,就说明存在梯度爆炸的问题。 ### 回答2: 梯度消失是指在深度神经网络训练过程中,梯度值逐渐减小至接近于零,导致网络参数无法得到有效的更新,从而影响模型的训练效果。具体来说,当梯度的数值呈现一种逐渐减小的趋势并且接近于零时,就可以认为是梯度消失。 在观察梯度打印结果时,我们可以关注以下几个方面来确定是否存在梯度消失的趋势: 1. 数值范围:观察梯度的数值范围,如果梯度的数值在传递过程中逐渐减小,并且最终接近于零,那么可能存在梯度消失的情况。 2. 逐层传播:观察梯度在网络的不同层之间传递时的变化情况。如果在网络的前向传播过程中,上层的梯度在经过多次传递后逐渐缩小,最终接近于零,那么可能表明梯度在传播过程中消失。 3. 反向传播:观察梯度在反向传播过程中的变化情况。如果在反向传播过程中,梯度在逐层传递后减小并且接近于零,那么就可以认为是梯度消失。 总之,当梯度的数值在传递过程中逐渐减小并且最终接近于零,无法有效地更新网络参数时,就可以判断存在梯度消失的趋势。梯度消失会导致训练过程变得困难,可能需要采取一些方式来缓解这个问题,例如使用梯度裁剪、使用不同的激活函数等。 ### 回答3: 梯度消失是指在神经网络训练过程中,当网络参数更新时,梯度的数值逐渐变小,最终趋近于零的现象。这种现象会导致网络无法正常学习,发生训练困难。 对于一个神经网络,梯度是指损失函数对于网络参数的偏导数。在前向传播过程中,通过不断对输入向前逐层进行运算,梯度值会根据网络结构的不同发生变化。如果在网络的某些层次,梯度值逐渐变小,导致后续层次的梯度也变小,使得最底层的参数更新几乎无效,就可以认为梯度消失出现了。 梯度消失的主要原因是由于深度神经网络的反向传播算法。在反向传播过程中,梯度值会不断地被上一层的权重乘以,通过层与层之间的乘法操作,梯度值会逐渐衰减。当网络层数很多时,该衰减现象会累积,使得梯度变得非常小甚至接近于零。这样一来,网络参数的更新就几乎没有作用,整个网络无法充分学习。 当梯度呈现出指数级下降的趋势,即随着层数的增加,梯度值迅速减小,甚至趋近于零时,就可认为梯度消失现象出现了。在这种情况下,网络的训练效果会变得很差,甚至无法收敛到最优解。 为了解决梯度消失问题,可以采用一些技巧,如使用更合适的激活函数(如ReLU),归一化数据以及使用更稳定的参数初始化方法(如Xavier和He初始化)。此外,还可以采用更先进的优化算法(如Adam)和更小的学习率等策略,来改善梯度消失问题,提升神经网络的训练效果。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值