亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

在數組中查找重復項

在數組中查找重復項

慕碼人8056858 2019-11-13 15:56:39
給定一個由n個整數元素組成的數組,您將如何在O(n)時間內查找該數組中是否存在重復項,而不使用任何額外的空間。如果有額外的空間,則意味著O(n)級的額外空間。Xor運算符是否以任何方式提供幫助。
查看完整描述

3 回答

?
繁華開滿天機

TA貢獻1816條經驗 獲得超4個贊

就地基數排序后進行線性掃描

就地基數排序算法


根據您實際認為的Radix排序的時間復雜度,此解決方案為O(N)時間,盡管我個人并不這么認為。我認為,如果您不對整數排序進行線性時間假設,那么該問題將無法解決。


由于排序是就地的,因此只需要O(1)額外的存儲。


代碼全為C ++ 11


步驟1:基數排序

template<typename T, typename std::enable_if<std::is_integral<T>::value>::type* = nullptr>

void RecurseOnRadixSort(std::vector<T>& myArray, T mask, int zerosEnd, int onesBegin)

{

    if (zerosEnd+1 >= onesBegin-1 || mask == 0) 

        return;


    int zerosEnd2 = zerosEnd;

    int onesBegin2 = onesBegin;

    while(zerosEnd2+1 <= onesBegin2-1)

    {

        // swap ones to the right

        if ((myArray[zerosEnd2+1] & mask) != 0)

        {

            std::swap(myArray[zerosEnd2+1], myArray[onesBegin2-1]);

            --onesBegin2;

        }

        else

            ++zerosEnd2;

    }


    mask >>= 1;


    //recurse on lhs

    RecurseOnRadixSort(myArray, mask, zerosEnd, zerosEnd2+1);


    //recurse on rhs

    RecurseOnRadixSort(myArray, mask, onesBegin2-1, onesBegin);

}


template <typename T, typename std::enable_if<std::is_integral<T>::value>::type* = nullptr>

void InPlaceRadixSort(std::vector<T>& myArray)

{

    int zerosEnd = -1;

    int onesBegin = static_cast<int>(myArray.size());

    T mask = static_cast<T>(1) << sizeof(T)*8-1;

    while(zerosEnd+1 <= onesBegin-1)

    {

        if ( (myArray[zerosEnd+1] & mask) != 0)

        {

            std::swap(myArray[zerosEnd+1], myArray[onesBegin-1]);

            --onesBegin;

        }

        else

            ++zerosEnd;

    }


    mask = static_cast<T>(1) << sizeof(T)*8-2; // need to reassign in case of signed datatype

    //recurse on lhs

    RecurseOnRadixSort(myArray, mask, -1, zerosEnd+1);

    //recurse on rhs

    RecurseOnRadixSort(myArray, mask, onesBegin-1, static_cast<int>(myArray.size()));


    // swap negatives to the front

    auto iterSmallest = std::min_element(myArray.begin(), myArray.end());

    if (*iterSmallest < 0)

    {

        std::reverse(myArray.begin(), myArray.end());

        iterSmallest = std::min_element(myArray.begin(), myArray.end());

        std::reverse(myArray.begin(), iterSmallest+1);

        std::reverse(iterSmallest+1, myArray.end());

    }

}

步驟2:線性掃描重復元素

for (size_t i=0, j=1; j<myArray.size(); ++i,++j)

{

    if (myArray[i] == myArray[j])

    {

        std::cout << "Found duplicate element " << myArray[i];

    }

}

完整的代碼

#include <iostream>

#include <string>

#include <vector>

#include <iostream>

#include <vector>

#include <algorithm>

#include <ctime>

#include <type_traits>

using namespace std;

#define N 10


template <typename T>

void PrintArray(const std::vector<T>& myArray)

{

    for (auto&& element : myArray)

    {

        std::cout << element << std::endl;

    }

}


template<typename T, typename std::enable_if<std::is_integral<T>::value>::type* = nullptr>

void RecurseOnRadixSort(std::vector<T>& myArray, T mask, int zerosEnd, int onesBegin)

{

    if (zerosEnd+1 >= onesBegin-1 || mask == 0) 

        return;


    int zerosEnd2 = zerosEnd;

    int onesBegin2 = onesBegin;

    while(zerosEnd2+1 <= onesBegin2-1)

    {

        // swap ones to the right

        if ((myArray[zerosEnd2+1] & mask) != 0)

        {

            std::swap(myArray[zerosEnd2+1], myArray[onesBegin2-1]);

            --onesBegin2;

        }

        else

            ++zerosEnd2;

    }


    mask >>= 1;


    //recurse on lhs

    RecurseOnRadixSort(myArray, mask, zerosEnd, zerosEnd2+1);


    //recurse on rhs

    RecurseOnRadixSort(myArray, mask, onesBegin2-1, onesBegin);

}


template <typename T, typename std::enable_if<std::is_integral<T>::value>::type* = nullptr>

void InPlaceRadixSort(std::vector<T>& myArray)

{

    int zerosEnd = -1;

    int onesBegin = static_cast<int>(myArray.size());

    T mask = static_cast<T>(1) << sizeof(T)*8-1;

    while(zerosEnd+1 <= onesBegin-1)

    {

        if ( (myArray[zerosEnd+1] & mask) != 0)

        {

            std::swap(myArray[zerosEnd+1], myArray[onesBegin-1]);

            --onesBegin;

        }

        else

            ++zerosEnd;

    }


    mask = static_cast<T>(1) << sizeof(T)*8-2; // need to reassign in case of signed datatype

    //recurse on lhs

    RecurseOnRadixSort(myArray, mask, -1, zerosEnd+1);

    //recurse on rhs

    RecurseOnRadixSort(myArray, mask, onesBegin-1, static_cast<int>(myArray.size()));


    // swap negatives to the front

    auto iterSmallest = std::min_element(myArray.begin(), myArray.end());

    if (*iterSmallest < 0)

    {

        std::reverse(myArray.begin(), myArray.end());

        iterSmallest = std::min_element(myArray.begin(), myArray.end());

        std::reverse(myArray.begin(), iterSmallest+1);

        std::reverse(iterSmallest+1, myArray.end());

    }

}


int main() {

    srand(time(NULL));

    std::vector<int> myArray(N);

    for (size_t i=0;i<myArray.size();++i)

    {

        myArray[i] = rand() % 100 * (rand() % 2 == 1?-1:1);

    }


    std::cout << "Vector before radix sort: " << std::endl;

    PrintArray(myArray);

    InPlaceRadixSort(myArray);

    std::cout << "Vector after radix sort: " << std::endl;

    PrintArray(myArray);


    for (size_t i=0, j=1; j<myArray.size(); ++i,++j)

    {

        if (myArray[i] == myArray[j])

        {

            std::cout << "Found duplicate element " << myArray[i];

        }

    }

    return 0;

}


查看完整回答
反對 回復 2019-11-13
?
暮色呼如

TA貢獻1853條經驗 獲得超9個贊

這是O(n)時間使用情況和O(1)空間使用情況的解決方案!


Traverse the array. Do following for every index i of A[].

{

    check for sign of A[abs(A[i])] ;

    if positive then        make it negative by   A[abs(A[i])]=-A[abs(A[i])];

    else  // i.e., A[abs(A[i])] is negative

    this   element (ith element of list) is a repetition

}


查看完整回答
反對 回復 2019-11-13
  • 3 回答
  • 0 關注
  • 929 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號