编程面试中最古老的技巧问题之一是:如何在不使用临时变量的情况下交换两个整数?这是我在C/C++面试中第一次被问到的问题,后来在各种Java面试中也被问过几次。这个问题的妙处在于,既要思考如何在不使用第三个变量的情况下交换两个数字的诀窍,又要思考与每种方法有关的问题。如果一个程序员能想到整数溢出,并在其解决方案中考虑到这一点,那么在面试官眼中就会产生很好的印象。
好了,让我们进入正题,假设你有两个整数i=10和j=20,你将如何在不使用任何变量的情况下交换它们,使j=10和i=20?虽然这是本杂志的问题,而且解决方案在其他每一种编程语言中都或多或少地起作用,但你需要用Java编程结构来做这件事。
你可以通过执行一些数学运算来交换数字,如加减法和乘除法,但它们面临着整数溢出的问题。
有一个巧妙的技巧,即使用XOR位操作符进行数字交换,这被证明是最终的解决方案。我们将在这里详细探讨和理解这三种解决方案,如果你渴望得到更多的编程问题和解决方案,你可以随时看看 Grokking the Coding Interview。编码问题的模式》,这是准备编程工作面试的最佳课程之一。
这与典型的编码问题课程不同。在这个课程中,你将学习到15种流行的编码模式,如双指针,快慢指针,滑动窗口蚀刻,这可以帮助你解决100多个Leetcode问题。它们很好地发展了编码意识和模式识别技能,在真正的编码面试中解决未知的编码问题。
在Java中不使用临时变量交换两个整数的2种方法
现在你已经熟悉了这个问题,让我们来谈谈解决方案。有两种主要方法来解决这个问题,一种是使用算术运算符,另一种是使用位运算符。第一种解决方法有一些漏洞,如溢出,如果你能在面试时提出来,也能为你赢得一些分数。
解决方案1--使用加法和减法
你可以使用Java中的+和-运算符来交换两个整数,如下图所示。
a
你可以看到,这是一个非常好的技巧,第一次花了一些时间来思考这个方法。我真的很高兴甚至想到了这个办法,因为它很整洁,但幸福是短暂的,因为面试官说,这不是在所有条件下都能工作。
他说,如果加法超过Integer.MAX_VALUE所定义的int primitive的最大值,而如果减法小于最小值,我指的是Integer.MIN_VALUE,那么整数将溢出。
这让我很困惑,我认输了,后来才发现这段代码绝对没问题,而且在Java 中完美运行,因为溢出被明确定义了。而且,是的,同样的解决方案在C或C++中是行不通的,但在Java中绝对可以正常工作。
不相信吗?这里有证据。
a = Integer.MAX_VALUE;
b = 10;
System.out.
这里两个数字的加法会溢出,Integer.MAX_VALUE + 10 = -2147483639,但我们也在做减法,这将补偿这个值,因为b现在是Integer.MAX_VALUE,-2147483639 - 2147483647将再次溢出,给你10作为输出。
如果你不熟悉不同的数据类型,包括原语和封装类,并想知道更多关于它们的限制和工作原理,那么我建议你参加一个全面的Java课程,如Udemy上的Tim Buchalaka和他的团队的**The Complete Java Masterclass**。
这门课程涵盖了所有的基础知识,包括我们将在下一节看到的位运算符,它也是最新的课程。你可以在Udemy的疯狂销售中以9.99美元的价格购买,这种销售每隔一段时间就会发生。
顺便说一下,在Python中解决这个问题和交换变量要容易得多,所以你在Python面试时极不可能遇到这个问题:-)
解决方案2--使用XOR技巧
在Java中交换两个整数而不使用临时变量的第二个解决方案被广泛认为是最好的解决方案,因为它也可以在不像Java那样处理整数溢出的语言中工作,例如C和C++。
如果你记得XOR真值表,那么你就知道,如果A和B不同,A XOR B将返回1 ,如果A和B相同,则返回 0。这个特性产生了下面的代码,也就是俗称的XOR技巧。
x = x ^
这是一个在Java中使用XOR位运算符交换两个数字的例子,你可以看到X和Y的值在第三次操作后被交换了。
如果你想了解更多关于Java中的位操作符和一般的编程,我强烈建议你阅读Henry S. Warren的《Hackers Delight》一书,它是学习位操作和位移操作的圣经,并由程序员专家进行还原。
不用临时变量交换两个整数的Java程序
在这个Java程序中,我将向你展示在不使用任何临时变量或第三个变量的情况下交换两个整数的几种方法,以及每种方法会带来什么问题,哪种方法在所有条件下都能工作。
实际上,这两种流行的解决方案在Java中完全可以正常工作,但候选人,特别是那些来自C和C++背景的人常常认为第一个解决方案是坏的,在整数边界上会失败,但事实并非如此。
整数溢出在Java中有明确的定义,比如Integer.MAX_VALUE + 1会导致Integer.MIN_VALUE,这意味着如果你用同一组数字做加法和减法,你的结果会很好,正如上面的例子中所看到的。
/**
* Java program to swap two integers without using temp variable
*
* @author java67
*/
以上就是关于如何在Java中不使用临时变量来交换两个整数的全部内容。与人们普遍认为的第一种解决方案在整数边界即最大值和最小值附近不起作用不同,这在C和C++等语言中也是如此,但它在Java中完全可以正常工作。为什么呢?因为溢出是明确定义的,而且加法和减法一起否定了溢出的影响。
第二种解决方案是毫无疑问的,因为它是最好的解决方案,不会受到任何符号或溢出问题的影响。它也被认为是在Java中不使用临时变量来交换两个数字的最快方法。
那么这个备忘录呢 :)
无论如何,如果你正在准备编程工作面试,并寻找一些好的资源,那么你也可以从以下书籍和课程中获得帮助,这是编程问题的最佳资源,并刷新你的数据结构和算法技能。 :
如果你对解决一些简单和一些棘手的编程问题感兴趣,我建议你看看以下一组编程问题 。
-
Java程序员的30大基于数组的编程问题?[问题]。
-
10本每个程序员都应该阅读的算法书籍(列表)。
-
5本学习Java中数据结构和算法的书?(书籍)
-
如何检查字符串是否是 Palindrome?(解决方案)
-
为Java程序员准备的前20个基于字符串的编码问题?[问题]。
-
针对Java程序员的10大编程和编码练习?[问题]
-
编码面试中的前50个Java程序(见此)。
-
如何使用迭代和递归在Java中反转字符串?(解决方案)
-
面试中的100多个数据结构编码问题(问题)
-
如何从整数数组中找出前两个数字?[解决方案]
-
如何在Java中不使用递归来打印斐波那契数列?[解决方案]
-
面向程序员的10个免费数据结构和算法课程(课程)
-
如何计算字符串中某个字符的出现次数?(解决方法)
-
如何查找Java字符串中的重复字符?[解决方案]
-
如何在Java中找到一个数字的平方根?[解决方案]
-
面向程序员的5个免费数据结构和算法课程(课程)
-
如何将数字字符串转换为int?(解决方案)
-
如何在不使用库方法的情况下将句子中的单词倒过来?(解决方法)
-
如何在Java中原地反转一个字符串?(解决方法)
-
如何编写程序来打印字符串中第一个不重复的字符?(解决方法)
感谢你到目前为止阅读这篇文章。如果你喜欢这个面试问题,那么请与你的朋友和同事分享它。
P. S.- 如果你正在寻找一些免费的算法课程来提高你对数据结构和算法的理解,那么你也应该看看Udemy上的**Java数据结构免费课程**。它是完全免费的,你只需要创建一个免费的Udemy账户来报名参加这个课程。