• LeetCode 287. Find the Duplicate Number


    原题链接在这里:https://leetcode.com/problems/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.

    题解:

    每次取 Math.abs(nums[i])为index, 然后跳到index上,如果这个数是正数,那么把它变成负数,如果是负数,说明之前已经有操作使其为负,就有重复,返回index. 有类似题目Find All Numbers Disappeared in an Array.

    Time Complexity: O(n). Space: O(1).

    AC Java:

     1 public class Solution {
     2     public int findDuplicate(int[] nums) {
     3         if(nums == null || nums.length == 0){
     4             throw new IllegalArgumentException("Invalid input array.");
     5         }
     6         
     7         for(int i = 0; i<nums.length; i++){
     8             int index = Math.abs(nums[i]);
     9             if(nums[index] > 0){
    10                 nums[index] = -nums[index];
    11             }else{
    12                 return index;
    13             }
    14         }
    15         
    16         //出了loop还没有返回 那么说明是error
    17         return -1;
    18     }
    19 }

    也可以采用First Missing Positive中swap的方法,把nums[i] swap到 index = nums[i]的位置上. 

    第二遍扫描时如果出现了i != nums[i]时,就是nums[i]是duplicate.

    Time Complexity: O(nums.length). Space: O(1).

    AC Java:

     1 class Solution {
     2     public int findDuplicate(int[] nums) {
     3         for(int i = 0; i<nums.length; i++){
     4             if(nums[i]>=0 && nums[i]<nums.length && nums[i]!=nums[nums[i]]){
     5                 swap(nums, i, nums[i]);
     6                 i--;
     7             }
     8         }
     9         
    10         for(int i = 0; i<nums.length; i++){
    11             if(nums[i] != i){
    12                 return nums[i];
    13             }
    14         }
    15         
    16         return -1;
    17     }
    18     
    19     private void swap(int [] nums, int i, int j){
    20         int temp = nums[i];
    21         nums[i] = nums[j];
    22         nums[j] = temp;
    23     }
    24 }

    居然能由此题联想到Linked List Cycle II也是厉害.

    这里的duplicate number就是cycle的起点. 课通过快慢指针找到cycle的起点.

    Note: 这里回置walker是回置到0. 而不是nums[0]. 因为接下来是跳动nums[runner], runner 是index. 

    Time Complexity: O(n). Space: O(1).

    AC Java:

     1 public class Solution {
     2     public int findDuplicate(int[] nums) {
     3         if(nums == null || nums.length == 0){
     4             throw new IllegalArgumentException("Invalid input array.");
     5         }
     6         
     7         //walker and runner can't start at the same point
     8         //or while loop condition walker != runner is never used
     9         //while loop is skipped.
    10         int walker = nums[0];
    11         int runner = nums[nums[0]]; 
    12         while(walker != runner){
    13             walker = nums[walker];
    14             runner = nums[nums[runner]];
    15         }
    16         
    17         walker = 0;
    18         while(walker != runner){
    19             walker = nums[walker];
    20             runner = nums[runner];
    21         }
    22         
    23         return walker;
    24     }
    25 }

    类似First Missing Positive.

  • 相关阅读:
    01 《i》控制字体大小 v-for循环绑定类名 v-bind 结合三目运算 动态添加类
    右侧是长方形和半圆结合 光标放上去在规定时间内完成动画
    04-align-content 它对于当单行是没有效果的
    03-flex-wrap是否换行
    02-align-items的用法
    01--顶部的通告特效---仅显示一条一条滚动
    洛谷P2392 kkksc03考前临时抱佛脚(01背包/搜索)
    蓝桥杯 9大臣的旅费(树的直径)
    蓝桥杯 8买不到的数目(数论/线性DP)
    蓝桥杯 7连号区间数(暴力or并查集(?)
  • 原文地址:https://www.cnblogs.com/Dylan-Java-NYC/p/4881212.html
Copyright © 2020-2023  润新知