第一篇博客,肯定是水的不要的,希望各位大佬多多指点。
非科班转入行业7年, 基本就是在做crud的工作,从这篇博客开始,希望是自己的改变的开始吧!话不多说,今天就来个初级算法题吧,超级简单的,整起来。因为是干java的,所以文中的代码都是用java作为实例。
题目:
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
比如:输入:nums = [9,9,7,2,2],输出:1
输入:nums = [20,14,12,30,14,12,20],输出:30
注意,我们主要关注的是算法的实现,所以实例方法中我们默认return为0即可;
首先,来说说第一种解法:
我们首先来找下规律,如果数组中存在某个数只出现一次,我们发现如果这个数组是有序的话,只要不是首尾的数字,该数字必然跟左右两边的数不相等。所以我们的解这道题的方法就是:
第一步,先判断数组的长度是否大于1,如果为1,那么该数组肯定是只出现一次,就不用比较了,所以我们直接返回该数字即可。
第二步,先将数组排序。
第三步,我们把首尾的数字分别单独比较,首尾的数字只需要判断跟它相邻的数字是否相等就可以了,如果不相等,那么这个只出现过一次的数字就是排序后的nums[0]或者nums[nums.length-1]。
第四步,我们从下标1开始遍历数组,将nums[i]分别跟前后的元素进行比较,如果跟前后的元素都不相等,那么这个只出现过一次的数字就是排序后的nums[i]。
代码如下:
public int alone(int[] nums) {
if (nums.length == 1) {
return nums[0];
}
Arrays.sort(nums);
if (nums.length > 1) {
if (nums[0] != nums[1]) {
return nums[0];
}
if (nums[nums.length - 2] != nums[nums.length - 1]) {
return nums[nums.length - 1];
}
for (int i = 1; i < nums.length - 1; i++) {
if (nums[i] != nums[i - 1] && nums[i] != nums[i + 1]) {
return nums[i];
}
}
}
return 0;
}
各位小伙伴,是不是觉得第一种解法很喽比,其实我也这么觉得。那么我就来介绍第二种解法。第二种解法几行代码就能搞定了,我们可以使用为运算符。我们使用位运算的异或来解决该题。
我们知道异或在二进制中,两个位相同为0,相异为1;
所以即为如下规律:
1^1=0;
1^0=1;
0^1=1;
0^0=0;
也就是说比如任意数字a:
0^a=a;
a^b=a;
a^a=0;
所以,我们就可以定义一个初始化为0的参数,遍历数组进行异或运算,然后直接返回该参数即可。代码如下:
public int alone2(int[] nums) {
int res = 0;
for (int num : nums) {
res = res ^ num;
}
return res;
}
第一次写博客,可能也没解释的太清楚,或者有考虑不周全的地方,还望各位大佬指出,非常感谢。