May Leetcode Speedrun问题:排序数组中的单个元素

时间:2020-10-17 16:54:42

标签: c++ arrays vector

所以我看着埃里希托完成了这些挑战,我惊讶于他解决“排序数组中的单个元素”的速度有多快。从初学者的角度来看,它确实令人印象深刻-也许对于高级开发人员而言,速度是相当正常的。

为您提供了一个排序的数组,其中所有元素都是整数,并且所有元素在该数组中恰好出现两次,除了一个元素恰好出现一次。 (即,除一个元素外,所有元素都重复。)您需要找到元素仅出现一次。

我只是在这里了解所说代码的工作原理:

class Solution { 
public:
    int singleNonDuplicate(vector<int>& nums) {
        long long a = 0;
        for(int x : nums) {
            a ^= x
        }
        return a;
    }
};

这是到目前为止我得到的: 对于向量/数组“ nums”中的每个整数“ x”,a等于a ^ x(如果我说的是正确的话)。

这是我的问题:

a ^ x是否等于0,因为a从开始就为0?

int singleNonDuplicate(vector<int> nums) {
//...
}

and

int singleNonDuplicate(vector<int>& nums) {
//...
}

我了解这一点:vector<int> nums按值传递(您正在使用函数内部的num的“副本”),而vector<int>& nums通过引用传递(您正在函数内部使用nums本身)。

如果要像Errichto一样解决问题,“&”是否重要?

ps:

  1. 很抱歉,从编程的角度来看可能会犯的错误,我可能不小心说了一些错误的话。
  2. 是的,我迟早会学习C ++,2020年是我人生中的第一年,实际上我的日程安排中有一个实际的“编程”课,这些视频很有趣,我很想知道为什么说的代码行得通&尝试了解等等。

2 个答案:

答案 0 :(得分:1)

休闲证明:

(如果您对可以帮助您提出这样的解决方案并理解它们的研究领域感兴趣,我建议您使用离散数学和群论/抽象代数。)

我想我知道您所引用的问题。像这样

为您提供了一个未排序的数组,其中所有元素都是整数,并且所有元素在该数组中恰好出现两次,除了一个元素恰好出现一次。 (即,除一个元素外,所有元素都是重复的。)

您在第一部分的正确位置上,为什么起作用。它利用了XOR的一些属性:

  • X ^ 0 = X
  • X ^ X = 0
  • 异或运算是可交换的和关联的。
# proof

# since XOR is commutative, we can take advantage
# of the fact that all elements except our target
# occur in pairs of two:

P1, P1 = Two integers of the same value in a pair.
T = Our target.

# sample unsorted order, array size = 7 = (3*2)+1
[ P3, P1, T, P1, P2, P3, P2 ]

# since XOR is commutative, we can re-arrange the array
# to our liking, and still get the same value as
# the XOR algorithm.

# here, we move our target to the front, and then group
# each pair together.  I've arranged them in ascending
# order, but that's not important:

[ T, P1, P1, P2, P2, P3, P3 ]

# write out the equation our algorithm is solving:
solution = 0 ^ T ^ P1 ^ P1 ^ P2 ^ P2 ^ P3 ^ P3

# because XOR is associative, we can use parens
# to indicate elements of the form X^X=0:
solution = T ^ (P1 ^ P1) ^ (P2 ^ P2) ^ (P3 ^ P3) ^ 0

# substitute X^X=0
solution = T ^ 0 ^ 0 ^ 0 ^ 0

# use X^0=X repeatedly
solution = T

所以我们知道运行该算法会给我们目标T。


使用&传递引用而不是传递值时:

您的理解是正确的。在这里,并没有真正的区别。

“按引用传递”使您可以就地修改原始值,而他不这样做。

“按值传递”会复制矢量,这不会对此处的性能产生有意义的影响。

因此,他获得了使用传递引用的风格点,并且如果您使用leetcode来证明自己作为软件开发人员的勤奋工作,很高兴看到,但这与他的解决方案无关。

答案 1 :(得分:0)

^ 是编码世界中的 XOR 运算,而不是幂运算(您假设我猜是这样)。

我不知道您在说什么问题,如果它找到数组中唯一的唯一元素(给隔一个元素两次),

然后解决的逻辑是

             **a XOR a equals 0 **

             **a XOR 0 equals a**

因此,如果我们对数组中存在的所有元素进行XOR,则对应于两次出现的元素将得到0。 剩下的唯一元素将与0进行XOR运算,因此我们得到了该元素。

第二个查询的答案是,每当您要修改数组时,我们都会通过引用传递它。

PS:我也是编程的新手。希望我能回答你的问题。