码迷,mamicode.com
首页 > 其他好文 > 详细

LeetCode 287. Find the Duplicate Number (找到重复的数字)

时间:2017-09-14 13:26:56      阅读:169      评论:0      收藏:0      [点我收藏+]

标签:之间   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:

  1. You must not modify the array (assume the array is read only).
  2. You must use only constant, O(1) extra space.
  3. Your runtime complexity should be less than O(n2).
  4. There is only one duplicate number in the array, but it could be repeated more than once.

 


 

题目标签: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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!