zoukankan      html  css  js  c++  java
  • leetcode笔记:Remove Duplicates from Sorted Array II

    一.题目描写叙述

    这里写图片描写叙述

    二.解题技巧

    这道题和Remove Duplicates from Sorted Array这道题是相似的。仅仅只是这里同意出现反复的数字而已,能够採用二分搜索的变种算法。仅仅只是增加了剔除和第一个元素同样的元素的过程。

    还有一个思路是增加一个变量。用于记录元素出现的次数。这题由于是已经排序的数组,所以一个变量就可以解决。假设是没有排序的数组,则须要引入一个hash表来记录出现次数。

    三.演示样例代码

    #include <iostream>
    #include <vector>
    
    class Solution
    {
    public:
        int RemoveDuplicatesII(int A[], int n, int dupNum) // dupNum为同意反复的次数
        {
            if (n < (dupNum + 1)) return n; // 数组元素过少,无需删除反复数据
    
            int num = dupNum; // 存放删除后数组的元素个数,至少有2个元素
            for (int i = dupNum; i < n; i++)
            {
                if (A[i] != A[num - dupNum])
                {
                    A[num++] = A[i]; // 使用不反复元素替换第num个元素的位置
                }
            }
            // 运行算法后,数组A的前num个元素是所求的一个集合
            return num;
        }
    };

    測试代码:

    #include <algorithm>
    #include "solution.h"
    using namespace std;
    
    int main()
    {
        int removeTime = 2; // 同意数组中每一个元素最多反复的次数
        int a[100];         // 定义一个存放100个元素的数组
        int n = 100;
        for (int i = 0; i < n; i++)
            a[i] = rand() % 10 - 5;
        sort(a, a + 100); // 要求在运行算法之前数组已经过排序
        cout << "原始数组:";
        for (int j = 0; j < n; j++)
            cout << a[j] << " ";
        cout << endl << endl;
    
        Solution remove;
        int result_num;
        result_num = remove.RemoveDuplicatesII(a, n, removeTime);
    
        for (int k = 0; k < result_num; k++) // 数组a中前result_num个元素是处理后的元素
            cout << a[k] << " ";
        cout << endl;
        cout << "删除反复多于" << removeTime << "次的数据后数组剩余" << result_num << "个元素" << endl;
    
        getchar();
        return 0;
    }

    一个測试结果:

    这里写图片描写叙述

    该方法有一定的扩展性,同意元素反复若干次。例如以下面情况元素同意反复最多5次:

    这里写图片描写叙述

    还有一种使用二分查找的方法:

    class Solution {  
    public:  
    
        int RemoveDuplicatesFromStart(int* A, int n)  
        {  
            int NumberOfDuplicates = 0;  
            int Start = A[0];  
    
            for (int Index = 1; Index < n; Index++)  
            {  
                if ( Start != A[Index])  
                {  
                    break;  
                }  
    
                NumberOfDuplicates++;  
            }  
    
            return NumberOfDuplicates;  
    
        }  
    
    
        int RemoveDuplicatesFromEnd(int* A, int n)  
        {  
            int NumberOfDuplicates = 0;  
            int Start = A[0];  
    
            for (int Index = n - 1; Index > 0; Index--)  
            {  
                if (Start != A[Index])  
                {  
                    break;  
                }  
    
                NumberOfDuplicates++;  
            }  
    
            return NumberOfDuplicates;  
        }  
    
    
    
        bool search(int A[], int n, int target)  
        {  
            if (n < 1)  
            {  
                return false;  
            }  
    
            if (n == 1)  
            {  
                if (A[0] == target)  
                {  
                    return true;  
                }  
    
                return false;  
            }  
    
            if (n == 2)  
            {  
                if (A[0] == target)  
                {  
                    return true;  
                }  
    
                if (A[1] == target)  
                {  
                    return true;  
                }  
                return false;  
            }  
    
    
            if (A[0] == target)  
            {  
                return true;  
            }  
    
            // remove the duplicates  
            int DuplicatesFromStart = RemoveDuplicatesFromStart(A, n);  
    
            if (DuplicatesFromStart == (n - 1))  
            {  
                return false;  
            }  
    
    
            int DuplicatesFromEnd = RemoveDuplicatesFromEnd(A, n);  
    
            if (DuplicatesFromEnd == (n - 1))  
            {  
                return false;  
            }  
    
            n = n - DuplicatesFromStart - DuplicatesFromEnd;  
    
            if (n < 2)  
            {  
                return false;  
            }  
    
            A = A + DuplicatesFromStart;  
    
            if (A[n / 2] == target)  
            {  
                return true;  
            }  
    
            if (A[0] > target)  
            {  
                if (A[0] < A[n / 2])  
                {  
                    return search((A + n / 2), (n - n / 2 ), target);  
                }  
    
                if (A[n / 2] < target)  
                {  
                    return search((A + n / 2), (n - n / 2), target);  
                }  
    
                return search(A, (n / 2), target);  
    
            }  
            else  
            {  
                if (A[0] < A[n / 2])  
                {  
                    if (A[n / 2] < target)  
                    {  
                        return search((A + n / 2), (n - n / 2), target);  
                    }  
                    return search(A, (n / 2), target);  
                }  
                return search(A, (n / 2), target);  
            }  
        }  
    };  
    

    四.体会

    第一种方法的时间复杂度O(n),空间复杂度O(1),支持in place运算,同一时候有一定的扩展性。

    若採用变种的二分搜索算法,其实则是增加了剔除和第一个元素同样的元素的过程,增加了这个过程之后,此时在最差情况下的时间复杂度为O(n)。

  • 相关阅读:
    Error[e46]: Undefined external "?V1" referred in AF
    总是遇到奇怪问题一
    BrokenPipeError: [Errno 32] Broken pipe
    Segment BANKED_CODE must be defined in a segment definition option (-Z, -b or -P)
    使用jupyter打开已存在的ipynb文件
    时钟控制命令
    中断系统以及外部中断
    pytorch上的循环层和全连接层操作
    02池化层
    距离毕业还有---100天
  • 原文地址:https://www.cnblogs.com/llguanli/p/7195493.html
Copyright © 2011-2022 走看看