zoukankan      html  css  js  c++  java
  • 442.Find All Duplicates in an Array

    参考博客

    不会这题,看了这篇博客后总结一下,这题主要有两种方法:

    第一种是归位法:

     1 void swap(int *a,int *b)
     2 {
     3     int temp=*a;
     4     *a=*b;
     5     *b=temp;
     6 }
     7 
     8 int* findDuplicates(int* nums, int numsSize, int* returnSize)
     9 {
    10     int *result=malloc(numsSize*(sizeof(int)));
    11     *returnSize=0;
    12     
    13     for(int i=0;i<numsSize;i++)
    14     {
    15         while(nums[i]!=i+1 && nums[nums[i]-1]!=nums[i])
    16         swap(&nums[i],&nums[nums[i]-1]);
    17     }
    18     
    19     for(int i=0;i<numsSize;i++)
    20     {
    21         if(nums[i]!=i+1)
    22         result[(*returnSize)++]=nums[i];
    23     }
    24     
    25     return result;
    26 }

    但是对于其中的均摊分析,还是不很理解。

    第二种归纳为“标记法”(在不需要额外空间的情况下来标记)

    大概分为三个步骤

    1.因为什么原因来标记一个位置

    2.用什么标记方法

    3.用什么方法判断这个标记

    所以对于上面提到的那篇博客的,剩余的两种方法都可以归纳为标记法

     1 int* findDuplicates(int* nums, int numsSize, int* returnSize)
     2 {
     3     int *result=malloc(numsSize*(sizeof(int)));
     4     *returnSize=0;
     5     
     6     for(int i=0;i<numsSize;i++)
     7         nums[nums[i]%(numsSize+3)-1]+=numsSize+3;
     8     
     9     for(int i=0;i<numsSize;i++)
    10     {
    11         if(nums[i]/(numsSize+3)>1)
    12         result[(*returnSize)++]=i+1;
    13     }
    14 
    15     return result;
    16 }

    上面是博客中提到的取余法

    分解来看:

    1.因为各元素出现次数不同来标记一个位置

    2.标记的方法是对一个位置上 的 元素 对应 的 位置 加上一个数,为了第三步的方便,可以加上numsSize+1或比它大的数

    3.检验这个标记的方法:对每个位置的新元素都除以第二步加的那个数,因为第二步已经规定加的那个数大于等于numsSize+1,所以当商等于零时,

    就是该位置本该出现的元素并没有出现,同理商为一则是出现了一次。。。。。。

    另一个标记的方法是取负

     1 int* findDuplicates(int* nums, int numsSize, int* returnSize)
     2 {
     3     int *result=malloc(numsSize*(sizeof(int)));
     4     *returnSize=0;
     5     
     6     for(int i=0;i<numsSize;i++)
     7     {
     8         int index=abs(nums[i])-1;
     9         
    10         if(nums[index]>0)
    11         nums[index]=-nums[index];
    12         else
    13         result[(*returnSize)++]=index+1;
    14     }
    15     
    16     return result;
    17 }

    和上面一种方法不同之处主要在标记的方法和判断标记的方法,而且它们是同时进行的。

    Yosoro
  • 相关阅读:
    面向对象实验 ——(二)类与对象
    [LeetCode] 957. Prison Cells After N Days
    [LeetCode] 32. Longest Valid Parentheses
    [LeetCode] 120. Triangle
    [LeetCode] 441. Arranging Coins
    [LeetCode] 79. Word Search
    [LeetCode] 1143. Longest Common Subsequence
    [LeetCode] 718. Maximum Length of Repeated Subarray
    [LeetCode] 332. Reconstruct Itinerary
    [LeetCode] 279. Perfect Squares
  • 原文地址:https://www.cnblogs.com/tclan126/p/6483608.html
Copyright © 2011-2022 走看看