Find the Duplicate Number - Floyd's Cycle Detection - Leetcode 287 - Python

Find the Duplicate Number - Floyd's Cycle Detection - Leetcode 287 - Python

NeetCode

3 года назад

243,425 Просмотров

Ссылки и html тэги не поддерживаются


Комментарии:

@techandmore12
@techandmore12 - 09.12.2023 22:21

What if we have a value equal to the index? Edit: nvm

Ответить
@heatah
@heatah - 02.12.2023 03:52

Glad I'm not the only one that thought this problem was absurd! Thank you for the explanation! 🙂

Ответить
@icositetrachoron7028
@icositetrachoron7028 - 27.11.2023 22:40

plot twist the expected solution was O(n2) with two loops

Ответить
@AlexanderLopez-yx4ck
@AlexanderLopez-yx4ck - 26.11.2023 07:01

im just confused as to why we are treating the array as a linked list? shouldnt we get an index out of bounds? why are the pointers looping?

edit: okay now i understand that the pointers are non-linear, but im still having trouble understanding the problem at all since this is an array not a linked list

Ответить
@hwang1607
@hwang1607 - 13.11.2023 01:45

You can solve this with binary search using pidgeonhole principle with solution found on leetcode from vanAmsen:
I think its possible to come up with this but still difficult, time complexity is also worse at nlogn

class Solution:
def findDuplicate(self, nums: List[int]) -> int:
l = 0
r = len(nums) - 1

while l < r:
m = l + (r-l)//2

count = 0
for num in nums:
if num <= m:
count += 1
if count > m:
r = m
else:
l = m + 1
return l

Ответить
@douglaschiang7030
@douglaschiang7030 - 04.11.2023 19:00

Hi @NeetCode, thanks a lot for making amazing videos.

The explanation is very clear here but I am not fully convinced by the idea that "fast pointer is at least 1 cycle faster then the slow one" so that we can write the fast distance as p + C - x + "1"C.

So I tried another approach:
I use the same setting as yours, so we have "p" previous nodes, and a cycle of "C" nodes and we assume the two nodes met at point "C - x" from the start of the cycle. So there are p + C = L nodes in total.
We know that the fast pointer is faster than the slow ones and have run more cycles in the loop. So I think we can say:
Fast pointer: d_f = p + mC + C - x
Slow pointer: d_s = p + nC + C - x

and m > n.

Now, if the fast pointer is k times faster than the slow ones, we have:
d_f = kd_s
p + (m + 1)C - x = k(p + (n + 1)C - x)

rearranging, gives:
p = x + [((m + 1) - k(n + 1))/(k - 1)]C

Now, we want to find the start of the cycle isn't it, but we do not know where it is and what we know are the start of the "linked list" and the meeting point only, so can we relate the distance between the start point to the start of the cycle, and the meeting point to the start of the cycle based on the fact that we have a cycle? If [((m + 1) - k(n + 1))/(k - 1)] is an integer, we can try to take mod(C) on both side, and that will give us an identity. If we have a very big cycle (C >= p), then we will have:
p = x

If we have a very small cycle (C < p), we can first express p in terms of the cycle size by p = y + rC, where y < C and r > 0, then taking mod on both side gives:
y = x

If we add rC back to both sides, then we will get:
p = x + rC

Looking the above, that actually means the distance of "p" actually equals the distance between the meeting point to the cycle starting point "x" (plus an arbitrary numbers of cycle if we have a very small cycle), which means we can move p steps the meeting point to find the start of the cycle.

This is why we can move one pointer back to the start point and then move both points at the same time until they meet to find the start of the cycle.

By the way, since I am using an arbitrary number "k" for the magnitude in speed differences, looks like Floyd's algo also works if the fast pointer is more than 2 times faster than the slow ones.

Ответить
@prammar1951
@prammar1951 - 31.10.2023 20:49

WOW, really loved that proof. Never studied this in uni thanks for your help

Ответить
@TheBestNameEverMade
@TheBestNameEverMade - 27.10.2023 09:43

Can't you just add the numbers up and determine the difference between the sequence of the sum(1 to N) = n*(n+1)/2 and the sum of the array?

ie
Duplicate = sum(array) - n*(n+1)/2

Ответить
@dthnick
@dthnick - 27.10.2023 02:53

this is such a bullshit problem

Ответить
@user-xf1qg7fp8t
@user-xf1qg7fp8t - 26.10.2023 16:35

The fast pointer is not guarranteed to loop twice
if p is really long and c is short, it will loop more than 2
so the distance fast pointer travelled becomes P + nC - X, at which im lost

Ответить
@thebosslevelstudios995
@thebosslevelstudios995 - 25.10.2023 12:48

github?

Ответить
@divyam69
@divyam69 - 24.10.2023 17:18

There's an another way you can do it in O(n) time and O(1) space which is more intuitive
This was my approach
for(int i=0;i<nums.size();i++)
{
int index = abs(nums[i]);
if(nums[index]<0)
{
return index;
}
nums[index] = -nums[index];
}

Ответить
@NazeerBashaShaik
@NazeerBashaShaik - 24.10.2023 11:30

Thank you very much, its a nice explanation. Thanks again for all the efforts you put into it.

Ответить
@rajeshseptember09
@rajeshseptember09 - 18.10.2023 14:28

That's right. Even Floyd wouldn't have resolved this problem in 30 minutes. It goes on to say that given the nature of such requirements in an interview, certain solutions are best memorized so that you could use them in a different situation or if the same problem comes up again.

Ответить
@alexl2512
@alexl2512 - 10.10.2023 19:29

A slightly better implementation.😊

def findDuplicate(self, nums: List[int]) -> int:
slow, fast = 0, 0
while True:
slow = nums[slow]
fast = nums[nums[fast]]
if slow == fast:
break

slow2 = 0
while slow != slow2:
slow = nums[slow]
slow2 = nums[slow2]

return slow

Ответить
@tinymurky7329
@tinymurky7329 - 07.10.2023 21:05

I will cry if I got this question in intervew

Ответить
@asdfasyakitori8514
@asdfasyakitori8514 - 04.10.2023 12:38

I like the fact that you disliked this problem

Ответить
@AnonYmous-yu6hv
@AnonYmous-yu6hv - 30.09.2023 12:55

You're right, I don't know why would anyone ask this question, nobody will know it unless they have super memory and saw it already and this doesn't let you learn anything about the interviewee.

Ответить
@bossmusa9075
@bossmusa9075 - 23.09.2023 15:27

Indexes are nodes and values in those indexes are next pointers ( to indexes). That how it is linked list

Ответить
@reqzonegaming7157
@reqzonegaming7157 - 20.09.2023 14:03

In example through logic once we reached to the 3

in first while loop we reached 3 so why can't we directly return nums[3]

which is answer 2.

Please answer anybody.

Ответить
@anassalah838
@anassalah838 - 20.09.2023 09:44

Thk from Egypt ❤

Ответить
@anassalah838
@anassalah838 - 20.09.2023 09:43

I really love u thk for all u do bro

Ответить
@harishankarkarthik3570
@harishankarkarthik3570 - 19.09.2023 17:07

I believe there's a slight inaccuracy in the drawing explanation node diagram. I think it should be 0 -> 1 -> 3 -> 2 -> 4 -> 2. (Basically, what I mean is node 1 is omitted).

Ответить
@Cheng-K
@Cheng-K - 19.09.2023 16:32

Thank you so much for the wonderful explanation! Really liked it

Ответить
@jagdeepsingh5699
@jagdeepsingh5699 - 19.09.2023 09:01

Beautiful Explanation

Ответить
@Sumeet_100
@Sumeet_100 - 19.09.2023 08:48

Thank You for this video

Ответить
@MP-ny3ep
@MP-ny3ep - 19.09.2023 07:40

Amazing explanation as always. Thank you so very much !!!

Ответить
@vuongbinhan
@vuongbinhan - 16.09.2023 21:20

Ah yes the "trivial" cycle linked list for a seemingly easy problem, this is why I suck so badly at LC style interview :(

Ответить
@whimsicalkins5585
@whimsicalkins5585 - 16.09.2023 17:46

Currently the problem has aroung 20 K likes. People really love this problem

Ответить
@faiqito6987
@faiqito6987 - 12.09.2023 23:19

you know its a beautiful algorithm when the code for it is so simple

Ответить
@user-lj6mx8pr4w
@user-lj6mx8pr4w - 07.09.2023 00:05

Actually this problem an be solved by using binary search when applying the pigeonhole principle. But your solution is also really interesting. Thanks for your helpful explanation !!

Ответить
@sebastianacostamolina9593
@sebastianacostamolina9593 - 05.09.2023 21:12

great explanation

Ответить
@amitshukla1495
@amitshukla1495 - 02.09.2023 11:28

sum of array - n*(n+1)/2

Ответить
@user-dj3hs4ff5v
@user-dj3hs4ff5v - 02.09.2023 01:36

could we calculate the sum of elements then subtract sum 1-n from it.
in current example it fill 12-10=2

Ответить
@atharvataras
@atharvataras - 26.08.2023 16:40

All this time I read the solutions on LeetCode and could not wrap my head around it. Then I read ALL INTEGERS IN THE RANGE (1-N) and I still could not understand how it worked.

Ответить
@soumyadeepdutta6759
@soumyadeepdutta6759 - 24.08.2023 05:19

Can be done this way? (taking a vector of 1e5 making it constant space right?)
class Solution {
public:
int findDuplicate(vector<int>& nums) {
vector<int> a(1e5+2,0);
for(auto t: nums)
{if(a[t])
return t;
a[t]++;}
return 0;
}
};

Ответить
@michaelshen8378
@michaelshen8378 - 22.08.2023 17:49

It should be plus nC there.

Ответить
@94mathdude
@94mathdude - 12.08.2023 11:03

Why is the beginning node 0 and not 1?

Ответить
@user-vn1yf4bi1y
@user-vn1yf4bi1y - 08.08.2023 18:10

You are really talanted in explaning complicated things, even I got it) Thank you <3

Ответить
@zenyujin_
@zenyujin_ - 04.08.2023 00:20

Help: do the numbers 0->3->-2->4-> ... represent the index or value of index? cause if it represents the value of each index, i thought it would be this
1->3>2>4>2->4-. and if it represents the index, i thought that it would be like this: 0->1->3>2>4>2->4-.

Ответить
@akshatsamdani
@akshatsamdani - 22.07.2023 20:38

I think this problem could be solved by binary search too.
Here is my code:
class Solution {
public:
int findDuplicate(vector<int>& nums) {
int n = nums.size();

int lo = 1;
int hi = n - 1;

while (lo < hi) {
int mid = lo + (hi - lo) / 2;

int count = 0;
for (int i = 0; i < n; i++) {
if (nums[i] <= mid) {
count++;
}
}

if (count > mid) {
hi = mid;
}
else {
lo = mid + 1;
}
}

return lo;

}
};

Ответить
@the-tankeur1982
@the-tankeur1982 - 15.07.2023 18:50

This problem amazed me

Ответить
@sase1017
@sase1017 - 15.07.2023 04:42

so good, much appreciate for your effort

Ответить
@letsgoooooo
@letsgoooooo - 14.07.2023 15:24

head node as 0 is correct but the node after it should be 1 not 3

Ответить
@brazlyn123
@brazlyn123 - 09.07.2023 20:40

I don't understand why p must equal x. If there is a linked list of 10 elements where each element points only to the next element (1->2->3->4...), and only the 10th element points to the 9th element, then the meeting point must be inside the loop at either the 9th or the 10th element and the start of the loop is at 9. The distance between the meeting point and the beginning of the loop is now either 1 or 0 and the distance from the beginning of the loop to the head of the list is 8 which is not equal to 0 or 1. Where am I going wrong?

Ответить
@indhumathi5846
@indhumathi5846 - 04.07.2023 21:42

understood

Ответить
@santosh_kumar_123
@santosh_kumar_123 - 20.06.2023 10:36

How can making a sum of array - sum of set of array returns the duplicate

Ответить