标签:之间 while code duplicate odi turn 算法题目 条件 where
Given an array nums containing n + 1 integers where each integer is between 1 and n (inclusive), prove that at least one duplicate number must exist. Assume that there is only one duplicate number, find the duplicate one.
Note:
O(n2)
.
题目标签:Array, Binary Search, Two Pointers
题目给了我们一个nums array, 让我们找到其中的重复数字。因为这一题有4个条件,所以有难度。1. 要求我们不能改动array;2. 只能用O(1)空间;3. 时间要小于O(n^2);4. 只有一个重复的数字,但是它可以出现最少1次。
方法1:
利用binary search。
题目给的数字是在 [1, n] 之间, array 的size 是 n+1。所以肯定有一个数字会至少出现2次。
分析一下:
如果n 是5,那么就会有1 2 3 4 5 一共5个数字的可能,而array size 是6,那么其中一个数字肯定会至少出现两次。
如果没有重复的数字,小于等于1的数字 出现的次数 等于 1;
小于等于2的数字 出现的次数 等于 2;
... 同理3;4;5。
如果有重复的数字,如果重复的是1,那么 小于等于1的数字 出现的次数 肯定大于1;
基于这个理论,我们可以在1 2 3 4 5 选出一个 mid, 遍历array来count 小于等于mid 的数字个数 小于等于 它自己mid 还是 大于 mid?
如果count 小于等于mid, 说明 1 到 mid 这些数字 没有重复项, 重复项在 右半边 mid 到n, 所以缩小到右半边继续搜索;
如果count 大于mid, 说明 1 到 mid 这些数字中 有重复项,缩小到 左半边继续搜索。
Java Solution:
Runtime beats 28.13%
完成日期:09/13/2017
关键词:Array, Binary Search
关键点:如果从1到n中 有重复项,那么必然有一个数字出现的次数至少是2次
1 class Solution 2 { 3 public int findDuplicate(int[] nums) 4 { 5 /* Solution 1: binary search */ 6 int low = 1, high = nums.length - 1; 7 8 while(low <= high) 9 { 10 int mid = low + (high - low) / 2; 11 int cnt = 0; 12 13 for(int a: nums) 14 { 15 if(a <= mid) 16 cnt++; 17 } 18 19 if(cnt <= mid) // meaning duplicate is on the right side 20 low = mid + 1; 21 else // if cnt > mid, meaning duplicate is on the left side 22 high = mid - 1; 23 24 } 25 26 return low; 27 } 28 }
参考资料:
http://bookshadow.com/weblog/2015/09/28/leetcode-find-duplicate-number/
方法2:O(n),利用slow 和fast 双指针 (还没搞懂,暂时放着吧)
LeetCode 算法题目列表 - LeetCode Algorithms Questions List
LeetCode 287. Find the Duplicate Number (找到重复的数字)
标签:之间 while code duplicate odi turn 算法题目 条件 where
原文地址:http://www.cnblogs.com/jimmycheng/p/7519870.html