• 442. 数组中重复的数据


    toc

    题目

    给定一个整数数组 a,其中1 ≤ a[i] ≤ n (n为数组长度), 其中有些元素出现两次而其他元素出现一次。

    找到所有出现两次的元素。

    你可以不用到任何额外空间并在O(n)时间复杂度内解决这个问题吗?

    示例:

    输入:
    [4,3,2,7,8,2,3,1]

    输出:
    [2,3]

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/find-all-duplicates-in-an-array
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

    瞎扯

    看到这题的第一反应,这题我熟,才刚做完448,还热和着呢。
    这题居然还是中等难度的, 448还是简单难度,咋感觉448还难些?难道是因为这个???


    448可以用额外空间,所以官方认为更简单???

    思路

    同样,将nums卷起来,通过内部元素计算下标,到下标所指位置去进行染色/标记。被标记的位置的元素也存在被用来计算下标的可能,所以染色/标记方式需要可逆。对nums进行遍历,当发现下标所指位置已经被标记,说明用于计算下标的元素就是重复的元素。记录下即可。

    代码

    class Solution {
    public:
        vector<int> findDuplicates(vector<int>& nums) {
            int iIndex = -1;
            int iOriginalSize = static_cast<int>(nums.size());
            int iData = iOriginalSize;
            nums.reserve(iOriginalSize * 2);        //先预留足够空间,后面有遍历添加操作 O(n),避免遍历添加过程频繁分配内存,影响性能
            for(int i = 0; i < iOriginalSize; i++){
                const auto& elem = nums[i];
                iIndex = std::abs(elem) - 1;        //1 ≤ a[i] ≤ n,所以需减1得到下标
                if(nums[iIndex] < 0){               //nums[iIndex]已被染色,也就是elem重复出现
                    nums.push_back(iIndex + 1);     //在原始数据末尾,记录该重复元素,index + 1为元素值
                    continue;
                }
                nums[iIndex] *= -1;
            }
            nums.erase(nums.begin(), nums.begin() + iOriginalSize); //去掉原始数据,保留后添加的重复数据  O(n)
    
            return nums;
        }
    };

    再瞎扯

    题目要求不使用额外空间,结果大家都使用了
    前面22%的提交范例使用了额外空间




    后面的也都用了额外空间
    我也使用了,只不过我是在原nums上增加的,这样稍微擦边球点????





    原创不易,转载请注明出处,谢谢
  • 相关阅读:
    参考__JAVA
    债券价格和通胀率
    C++ 面试题
    欧式和美式期权
    explicit
    smart pointer
    const pointer
    manacher-马拉车算法
    输入有空格的字符串的2种方法
    bind()与connect()——计网中socket的使用
  • 原文地址:https://www.cnblogs.com/Keeping-Fit/p/14787190.html
Copyright © 2020-2023  润新知