From cebf10de23726c44377e9c8ba8957e211dfce98a Mon Sep 17 00:00:00 2001 From: gameloader Date: Mon, 25 Mar 2024 00:16:14 +0800 Subject: [PATCH] leetcode update --- content/posts/leetcode.md | 43 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/content/posts/leetcode.md b/content/posts/leetcode.md index 320d1b6..2f74579 100644 --- a/content/posts/leetcode.md +++ b/content/posts/leetcode.md @@ -1972,3 +1972,46 @@ func reorderList(head *ListNode) { } } ``` + +## day27 2024-03-24 + +### 287. Find the Duplicate Number + +Given an array of integers nums containing n + 1 integers where each integer is in the range [1, n] inclusive. + +There is only one repeated number in nums, return this repeated number. + +You must solve the problem without modifying the array nums and uses only constant extra space. + +![0324Ckibjiatyqu7](https://testingcf.jsdelivr.net/gh/game-loader/picbase@master/uPic/0324Ckibjiatyqu7.png) + +### 题解 + +根据鸽笼原理, 显然必有一个数字有一个重复数字. 最简单的思路就是用每个数和数组其余数字比较, 直到找到相同的数为止, 显然这个方法的时间复杂度比较高, 要O(n^2). 最终并没有想出题目中要求的时间复杂度为O(n), 空间复杂度为O(1)的解法, 看题解得知使用的是Floyd 循环检测算法, 这个算法一般用于检测链表中是否存在环, 即使用快慢指针, 同时遍历链表, 如果存在环, 快指针最终会追上慢指针. 如果链表没有环, 则遍历链表最终会到达空指针自然停止, 这里的快慢指针是给了未知长度的链表一个停止条件, 可以避免若链表有环无限循环遍历下去. 这里将数组堪称链表是非常精妙的思路, 将数组中的值看作下一个节点在数组中的下标, 这样如果有两个节点相同, 则最终快指针和慢指针指向的下标会相同, 再从头遍历一次数组, 找到值为这个下标的数据, 即为重复的数. + +### 代码 + +```go +func findDuplicate(nums []int) int { + // Step 1: Find the intersection point of the two pointers + slow := nums[0] + fast := nums[0] + + for { + slow = nums[slow] + fast = nums[nums[fast]] + if slow == fast { + break + } + } + + // Step 2: Find the entrance to the cycle (duplicate number) + slow = nums[0] + for slow != fast { + slow = nums[slow] + fast = nums[fast] + } + + return slow +} +```