【算法】解题总结:剑指Offer 50 数组中重复的数字(2 种方法)、剑指Offer 48 不用加减乘除做加法

JZ50 数组中重复的数字

(简单)

题目

描述
在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任一一个重复的数字。 例如,如果输入长度为7的数组[2,3,1,0,2,5,3],那么对应的输出是2或者3。存在不合法的输入的话输出-1

示例
输入:
[2,3,1,0,2,5,3]
返回值:
2
说明:
2或3都是对的

思路

哈希法或者暴力解法都可以通过(因过于简单,不再赘述),但是没有用到条件:“所有数字都在0到n-1的范围内”,因此,很可能还有更巧妙的方法。

实现

暴力解法

public class Solution {
    public int duplicate (int[] numbers) {
        if (numbers.length == 0) {
            return -1;
        }

        for (int i = 0; i < numbers.length - 1; i++) {
            for (int j = i + 1; j < numbers.length; j++) {
                if (numbers[i] == numbers[j]) {
                    return numbers[i];
                }
            }
        }

        return -1;
    }
}

在这里插入图片描述
哈希解法

public class Solution {
    public int duplicate (int[] numbers) {
        HashSet<Integer> set = new HashSet<Integer>();
        for(int i=0; i<=numbers.length-1; ++i){
            if(set.contains(numbers[i]))return numbers[i];
            else set.add(numbers[i]);
            //利用set的STL性质(add时有重复返回false)可以优化效率,将上面两句替换为:
            //if(!set.add(numbers[i]))return numbers[i];
        }
        return -1;
    }
}

在这里插入图片描述

JZ48 不用加减乘除做加法

(简单)

题目

描述
写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/四则运算符号。

示例
输入:
1,2
返回值:
3

思路

因为我这学期刚学完计算机组成原理,一看到这题,不用 +、-、*、/ 来计算两数之和,接着就想到了位运算,而 Java 中的位运算有:与(&)、或(|)、异或(^)、非(~),而此题只需要前三个即可。

两数相加的底层二进制实现,无非就是补码的运算,而此题并不是让考察原码和补码直接的转换,而考察的是对于位运算的熟悉程度和变通能力。

因为本题用位运算解决,因此为了方便起见,我们将加数和被加数都叫做两个二进制操作数。两个二进制操作数相加的结果,就是他们的未进位时的结果,加上进位数,而未进位时的结果可通过两数异或运算求得,进位数可通过两数与运算求得,因此,用一个 5 + 1 = 6 的例子来描述,则如下图所示:

在这里插入图片描述

实现

public class Solution {
    public int Add(int num1,int num2) {
        while (num2 != 0) {
            int x = (num1 & num2) << 1; //进位:求与,并左移
            num1 ^= num2; //未进位时的和:异或
            num2 = x;
        }
        return num1;
    }
}

在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

超周到的程序员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值