zoukankan      html  css  js  c++  java
  • [LeetCode] 287. Find the Duplicate Number

    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.

    Example 1:

    Input: [1,3,4,2,2]
    Output: 2
    

    Example 2:

    Input: [3,1,3,4,2]
    Output: 3

    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.

    题意是在一个数组中找到重复的数字。数组包含N + 1个数字,数字在1 <= x <= n之间。两种解法。

    1. 二分法。注意数组是无序的。当得到数组长度len和数组长度的一半mid之后,用count记录有多少个数小于等于中间数mid。举个例子,如果数组长度是10,mid则是5,这里mid指的是数组长度的一半。如果小于mid的个数大于数组的一半,说明重复的数字一定是小于mid的;反之如果大于mid的个数过半,重复的数字一定是大于mid的。用二分法逐渐逼近这个值,注意return的是start。

    时间O(nlogn)

    空间O(1)

    Java实现

     1 class Solution {
     2     public int findDuplicate(int[] nums) {
     3         int min = 0;
     4         int max = nums.length - 1;
     5         while (min <= max) {
     6             int mid = min + (max - min) / 2;
     7             int count = 0;
     8             for (int i = 0; i < nums.length; i++) {
     9                 if (nums[i] <= mid) {
    10                     count++;
    11                 }
    12             }
    13             if (count > mid) {
    14                 max = mid - 1;
    15             } else {
    16                 min = mid + 1;
    17             }
    18         }
    19         return min;
    20     }
    21 }

    JavaScript实现

     1 /**
     2  * @param {number[]} nums
     3  * @return {number}
     4  */
     5 var findDuplicate = function(nums) {
     6     let start = 1;
     7     let end = nums.length - 1;
     8     while (start < end) {
     9         let middle = Math.floor((start + end) / 2);
    10         let count = 0;
    11         // 计算总数组中有多少个数小于等于中间数
    12         for (let i = 0; i < nums.length; i++) {
    13             if (nums[i] <= middle) {
    14                 count++;
    15             }
    16         }
    17 
    18         if (count <= middle) {
    19             start = middle + 1;
    20         } else {
    21             end = middle;
    22         }
    23     }
    24     return start;
    25 };

    2. 快慢指针。因为数组一定是有重复数字出现的所以可以用快慢指针的思路做。当快慢指针相遇之后,再走第二遍,找到重复的数字。

    时间O(n)

    空间O(1)

    Java实现

     1 class Solution {
     2     public int findDuplicate(int[] nums) {
     3         int len = nums.length;
     4         if (len > 1) {
     5             int slow = nums[0];
     6             int fast = nums[nums[0]];
     7             while (slow != fast) {
     8                 slow = nums[slow];
     9                 fast = nums[nums[fast]];
    10             }
    11             slow = 0;
    12             while (slow != fast) {
    13                 slow = nums[slow];
    14                 fast = nums[fast];
    15             }
    16             return slow;
    17         }
    18         return -1;
    19     }
    20 }

    JavaScript实现

     1 /**
     2  * @param {number[]} nums
     3  * @return {number}
     4  */
     5 var findDuplicate = function(nums) {
     6     const len = nums.length;
     7     if (len > 0) {
     8         let slow = nums[0];
     9         let fast = nums[nums[0]];
    10         while (slow !== fast) {
    11             slow = nums[slow];
    12             fast = nums[nums[fast]];
    13         }
    14         slow = 0;
    15         while (slow !== fast) {
    16             slow = nums[slow];
    17             fast = nums[fast];
    18         }
    19         return slow;
    20     }
    21     return -1;
    22 };

    LeetCode 题目总结

  • 相关阅读:
    H5图片裁剪升级版(手机版)
    仿IOS 开关按钮
    JS 数字转换为大写金额
    Unity UGUI——遮罩效果(Mask)
    AdTime:多屏时代下传统媒体的鼓起
    C语言中随机数相关问题
    在vc中使用xtremetoolkit界面库-----安装及环境配置
    初识HTML 5:关于它的三个三
    移动中间件产品的解决方式
    Android ListView 常见问题与使用总结
  • 原文地址:https://www.cnblogs.com/cnoodle/p/11723719.html
Copyright © 2011-2022 走看看