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 题目总结

  • 相关阅读:
    hihoCoder[Offer收割]编程练习赛1题目解析
    你的计划为什么运行不下去?怎么破?
    Activity的生命周期
    leetcode——Lowest Common Ancestor of a Binary Tree
    Spring学习笔记(四)-- Spring事务全面分析
    Docker技术-cgroup
    docker高级应用之cpu与内存资源限制(转)
    JMX 学习
    如何使用JVisualVM进行性能分析
    如何利用 JConsole观察分析Java程序的运行,进行排错调优(转)
  • 原文地址:https://www.cnblogs.com/cnoodle/p/11723719.html
Copyright © 2011-2022 走看看