寻找数组中消失或重复的数字方法归纳

前言

在力扣网连续写了几道寻找数组中消失数字以及重复数字的题,发现有一些解法真是过于精妙,那就记录一波咯~~~~废话不多说开始吧!

剑指 Offer 03. 数组中重复的数字

找出数组中重复的数字。

在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。
力扣原题传送门
在这里插入图片描述

1、哈希表法

使用哈希表记录出现过的数字,一边遍历数组一边查询此数是否存在于哈希表中

class Solution {
    
    
public:
    int findRepeatNumber(vector<int>& nums) {
    
    
        unordered_set<int> historyNums;
        for(auto& p:nums){
    
    
            if(!historyNums.count(p))
                historyNums.insert(p);
            else return p;
        }
        return -1;
    }
};

一次遍历,时间复杂度O(N),使用哈希额外空间,空间复杂度O(N);

2、标记法

巧妙之处在于 nums 里的所有数字都在 0~n-1 的范围内 ,刚好对应的是长度为n的数组下标,我们如果将数组中的元素当做下标使用,将这个数加上一个长度 n ,如果遍历过程发现一个数已经大于n - 1,说明该数之前被标记过,所以下标对应值就是我们需要寻找的重复数字。

class Solution {
    
    
public:
    int findRepeatNumber(vector<int>& nums) {
    
    
        int len=nums.size();
        for(auto& p:nums){
    
    
            int index=p % len;
            if(nums[index]>=len) 
            	return index;
            nums[index] += len;
        }
        return -1;
    }
};

一次遍历,时间复杂度O(N),使用了常数空间,空间复杂度O(1);

448. 找到所有数组中消失的数字

给定一个范围在 1 ≤ a[i] ≤ n ( n = 数组大小 ) 的 整型数组,数组中的元素一些出现了两次,另一些只出现一次。

找到所有在 [1, n] 范围之间没有出现在数组中的数字。

扫描二维码关注公众号,回复: 12487221 查看本文章

您能在不使用额外空间且时间复杂度为O(n)的情况下完成这个任务吗? 你可以假定返回的数组不算在额外空间内。
原题传送
在这里插入图片描述

标记法

是不是似曾相识的感觉,没错,数组中的元素数值在 1~n 之间,与数组下标 0~n -1 相差为1,因此我们依然可以将这些元素减一的值当做下标使用进行标记,标记完我们再次遍历数组,若发现大于 0 的数,说明此数未被标记,那么它所对应的下标值加一的这个数肯定不在数组中(说得比较乱,可能代码比较好理解一些)

class Solution {
    
    
public:
	vector<int> findDisappearedNumbers(vector<int>& nums) {
    
    
		int n = nums.size();
		for (int i = 0; i < n; i++) {
    
    //遍历数组进行标记
			int index = abs(nums[i]) - 1;//下标需要取绝对值,因为有些元素被标记成了负数
			if (nums[index] > 0)//已经被标记过一次的数就不需要再次标记
				nums[index] = 0 - nums[index];
		}

		vector<int> res;
		for (int i = 0; i < n; i++)
			if (nums[i] > 0)
				res.push_back(i + 1);

		return res;
	}
};

先到这里,持续更新~~~

猜你喜欢

转载自blog.csdn.net/Genius_bin/article/details/113803055