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

  • 相关阅读:
    mysql 导入excel 或 .csv
    导出Excel
    jQuery.ajax
    在web项目中配置log4j
    数据分析入门
    jdbc的配置(更新中)
    Maven中项目的启动
    Maven中的配置文件
    Maven的插件管理
    Maven的依赖管理
  • 原文地址:https://www.cnblogs.com/cnoodle/p/11723719.html
Copyright © 2020-2023  润新知