• 不使用临时变量交换2个数字的三种方法


    题目

    编写一个函数,不用临时变量,直接交换numbers = [a, b]中a与b的值。
    示例:

    输入: numbers = [1,2]
    输出: [2,1]
    

    提示:

    • numbers.length == 2

    实现代码及解题思路

    注意:方法二只是思路,实际会存在溢出问题。

    /**
        * 方法一:根据差值, 来移动a, b
        * 如下图所示, a, b为数轴上2点, 可以利用a, b之间的距离不变, 来交换a和b
        *
        * ------------
        * a          b
        *
        * b = b - a; // 此时b是线段ab长
        * a = a + b; // 此时a到原b位置
        * b = a - b; // 此时b到原a位置
        * @param numbers
        * @return
        */
    public int[] swapNumbers_1(int[] numbers) {
        if (numbers.length != 2) return numbers;
        numbers[1] = numbers[1] - numbers[0];
        numbers[0] = numbers[0] + numbers[1];
        numbers[1] = numbers[0] - numbers[1];
    
        return numbers;
    }
    
    /**
        * 方法二:用b作为中点,先将a移动到以b为中点的对称位置a1=2b-a,
        * 然后将b以b为中点移动至a1的对称位置,也就是原来a所在位置,这样b1=a0,
        * 再将a从a1移动至a1和b1中点,也就是原来b所在位置,这样a2=b0
        *
        * a = 2*b - a;
        * b = 2*b - a;
        * a = (a + b) / 2;
        *
        * @note 该方法理论上可行,不过存在溢出的问题,
        * 当numbers[1] * 2溢出,或者该乘积-numbers[0]溢出,会导致存储的中间结果出错
        * 考虑,如果用a/b中点作为锚点,虽然不会溢出,不过在/2运算时,可能存在损失精度问题
        * 另外,第一次+运算,有可能产生溢出问题
        * a = (a + b) / 2;
        * b = 2a - b;
        * a = 2a - b;
        */
    public int[] swapNumbers_2(int[] numbers) {
        if (numbers.length != 2) return numbers;
    
        // 以b为中点,交换ab
        /*
        numbers[0] = numbers[1] * 2 - numbers[0];
        numbers[1] = numbers[1] * 2 - numbers[0];
        numbers[0] = (numbers[0] + numbers[1]) / 2;
            */
    
        // 以ab中点为中点,交换ab
        numbers[0] = (numbers[0] + numbers[1]) / 2;
        numbers[1] = 2*numbers[0] - numbers[1];
        numbers[0] = 2*numbers[0] - numbers[1];
    
        return numbers;
    }
    
    /**
        * 异或运算
        * 0^0 = 0
        * 0^1 = 1
        * 1^0 = 1
        * 1^1 = 0
        * 异或运算a^b可以理解成,消去a∪b中与ab相同的部分(a∩b),即a^b = a∪b - a∩b,这里a、b都是集合
        * a = a^b; // 此时a1 = a∪b -a∩b, 也就是a和b不相交的所有元素
        * b = a^b; // 此时b1 = a1∪b - a1∩b = a0,也就是原来的a
        * a = a^b; // 此时a2 = a1∪b1 - a1∩b1 = b0,也就是原来的b
        *
        */
    public int[] swapNumbers(int[] numbers) {
        if (numbers.length != 2) return numbers;
        numbers[0] = numbers[0]^numbers[1];
        numbers[1] = numbers[0]^numbers[1];
        numbers[0] = numbers[0]^numbers[1];
    
        return numbers;
    }
    

    面试题 16.01. 交换数字 | LeetCode

  • 相关阅读:
    C++中 destory() 和deallocate()以及delete函数的相关性和区别性
    由STL所想到的 C++显示调用析构函数
    MINIX3 内核整体架构回顾及内核定 性分析
    有一个无效 SelectedValue,因为它不在项目列表中
    SqlParameter.Value = NULL 引发的数据库异常
    前端解决跨域问题的8种方案(最新最全)
    SQL语句优化技术分析 整理他人的
    暂时未整理 已打印
    .Net_把文件数据添加到数据库中(面试题)
    ASP.NET中application对象的用法(面试题)
  • 原文地址:https://www.cnblogs.com/fortunely/p/14129406.html
Copyright © 2020-2023  润新知