从Sorted Array中删除重复项

时间:2016-06-01 16:15:15

标签: c++ vector duplicates sorted

Qus:从Sorted Array中删除重复项 给定一个排序数组,删除重复项,使每个元素只出现一次并返回新长度。

请注意,即使我们希望您返回新的长度,也请务必更改原始数组

不要为另一个数组分配额外的空间,必须使用常量内存来执行此操作。

我尝试了以下代码,任何人都可以帮助我出错的地方吗?

   #include<iostream>
    #include<vector>
    using namespace std;

    int removeDuplicates(vector<int> &A) {
        int m=A.size();
        if(m<=1) return m;
        vector<int> :: iterator i=A.begin();
        vector<int> :: iterator j=A.begin()+1;
        vector<int> :: iterator temp;
        while(i!=A.end() && j!=A.end())
        {
            while(j!=A.end() && *i == *j)
            {
                temp=j;
                j++;
                A.erase(temp);
            }
            i=j;
            j++;
        }
        return A.size();
    }

    int main()
    {
        vector<int> vec={0,0,0,0,0,0,0,4,4,7,7,7,7,9};
        cout<<"ans="<<removeDuplicates(vec);
        return 0;
    }

4 个答案:

答案 0 :(得分:1)

当你增加j,然后erase那里的元素时,从j + 1开始的元素向下移动。你通过递增来跳过一个元素。

更好的方法是简单地将非重复元素从一个迭代器复制到另一个迭代器,并在主循环结束时设置新长度。您当前的方法可能是O(n ^ 2),实际使用速度太慢。

答案 1 :(得分:0)

要求您使用数组。虽然矢量在很多方面都相似,但它并不相同。看看下面的示例代码。

此外,还要求您保持内存分配相同。您无法确保使用向量,一旦添加/删除元素,它的大小就会增大/缩小,当删除元素时,向量后面的数组中的数据将被重新分配和重写。

>>> a = ["foo", "bar", "baz"]
>>> for i in range(-1, -1*(len(a)+1), -1):
...     print i, a[i]
... 
-1 baz
-2 bar
-3 foo

答案 2 :(得分:0)

我认为这是你需要的。此函数从尾部到头部循环数组并计算相同的值。然后在ununique上执行已经唯一值的移位。 它不会改变向量到期过程的实际大小,因为它可能涉及向量内部的内存重新分配。

int removeDuplicates(vector<int> &vec) {
    int currentVal = vec.size() - 1;
    int uniqueNumber = 0;

    while (currentVal >= 0) {
        ++uniqueNumber;
        int sameVal = currentVal;
        while (sameVal > 0 && vec[sameVal - 1] == vec[currentVal])
            --sameVal;

        int shiftSize = uniqueNumber;
        for (int k = 1; k < shiftSize; ++k) {
            vec[sameVal + k] = vec[currentVal + k];
        }

        currentVal = sameVal - 1;
    }
    return uniqueNumber;
}

答案 3 :(得分:-1)

你可以使用像这样的迭代器来做到这一点:

;WITH CTE
    AS (SELECT o.Number AS 'OrderNo'
            , s.FullName AS 'CPC Emp'
            , CASE
                WHEN t.description = 'Loan Package to Lender' THEN t.CompletedDate
                ELSE NULL
             END AS 'Loan Pck To Lender'
            , CASE
                WHEN t.description = 'Recording Audit' THEN t.CompletedDate
                ELSE NULL
             END AS 'Recording Audit'
            , CASE
                WHEN t.description = 'Recorded Docs' THEN rt.RequestedDate
                ELSE NULL
             END AS 'Recorded Docs Requested'
            , CASE
                WHEN t.description = 'Recorded Docs to Lender' THEN t.CompletedDate
                ELSE NULL
             END AS 'Recorded Docs to Lender'
            , CASE
                WHEN t.description = 'Recorded Docs to Purchaser' THEN t.CompletedDate
                ELSE NULL
             END AS 'Recorded Docs to Purchaser'
            , CASE
                WHEN t.description = 'Title Policy to Lender' THEN t.CompletedDate
                ELSE NULL
             END AS 'TP to Lender'
            , CASE
                WHEN t.description = 'Title Policy to Purchaser' THEN t.CompletedDate
                ELSE NULL
             END AS 'TP Purchaser'
        FROM   pf.OrderInfo oi
             INNER JOIN pfm.[Order] o ON o.RootId# = oi.rootid
             INNER JOIN core.Profile op ON oi.OwningProfileID = op.ID
             INNER JOIN zref.OrderStatus os ON oi.OrderStatus = os.ID
             INNER JOIN zref.ProductType pt ON o.ProductTypeID = pt.ID
                                        AND pt.ID <> '15'
             INNER JOIN pfm.Task t ON t.RootId# = oi.RootID
                                 AND t.Description IN('Loan Package to Lender', 'Recording Audit', 'Recorded Docs to Lender', 'Recorded Docs to Purchaser', 'Title Policy to Lender', 'Title Policy to Purchaser', 'Recorded Docs')
             LEFT OUTER JOIN pfm.RequestedTask rt ON rt.RootId# = t.RootId#
                                             AND rt.Id# = t.Id#
                                             AND rt.LastId# = t.LastId#
             LEFT OUTER JOIN core.SecurityIdentity s ON s.ID = t.CompletedByID
        WHERE  (op.Name LIKE 'BH104%' -- Profiles Begin.
              OR op.name LIKE 'WO115%' --Profiles End.
             )
             AND t.CompletedDate BETWEEN '2016-1-1' AND '2016-4-30'
             AND s.fullname IS NOT NULL
        GROUP BY s.fullname
             , o.Number
             , t.Description
             , t.CompletedDate
             , rt.RequestedDate)
    SELECT CTE.OrderNo
        , CTE.[CPC Emp]
        , [Loan Pck To Lender]=MAX(CTE.[Loan Pck To Lender])
        , [Recording Audit]=MAX(CTE.[Recording Audit])
        , [Recorded Docs Requested]=MAX(CTE.[Recorded Docs Requested])
        , [Recorded Docs to Lender]=MAX(CTE.[Recorded Docs to Lender])
        , [Recorded Docs to Purchaser]=MAX(CTE.[Recorded Docs to Purchaser])
        , [TP to Lender]=MAX(CTE.[TP to Lender])
        , [TP Purchaser]=MAX(CTE.[TP Purchaser])
    FROM   CTE
    GROUP BY [OrderNo]
          , [CPC Emp]
    ORDER BY [CPC Emp];