剑指 Offer 03. 数组中重复的数字(C++实现)

03. 数组中重复的数字

一、题目描述

找出数组中重复的数字。

在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。
输入:[2, 3, 1, 0, 2, 5, 3]
输出:2 或 3

限制:

2 <= n <= 100000

二、解题思路

1、原地置换法

数组元素的 索引和值是 一对多的关系。 因此,可遍历数组并通过交换操作,使元素的索引与 值一一对应(即 nums[i]=i )。这样就能通过索引映射对应的值,起到与字典等价的作用。

nums[i] 2 3 1 0 2 5 3
i 0 1 2 3 4 5 6

算法流程:

①、判断vector容器是否为空;
②、初始值为 i=0开始遍历数组 nums :
③、判断nums[i]与i的关系,如果nums[i]=i ,则说明此数字已在对应索引位置,无需交换;如果不相等,则进行交换 temp = nums[nums[i]]; nums[nums[i]]=nums[i]; nums[i]=temp; 直到nums[i]=i; i+1进入下一次遍历;
④、如果nums[nums[i]]=nums[i] ,代表索引 nums[i] 处和索引 i 处的元素值都为 nums[i],即为我们要找的重复数字

复杂度分析:

时间复杂度 O(N): 遍历数组使用 O(N) ,每轮遍历的判断和交换操作使用 O(1);
空间复杂度 O(1): 使用常数复杂度的额外空间。

具体程序实现:

扫描二维码关注公众号,回复: 13309136 查看本文章
#include <iostream>
#include <vector>
using namespace std;

void printVecotr(vector<int>& v)
{
    
    
	for(vector<int>::iterator it = v.begin(); it != v.end(); it++)
	{
    
    
		cout << *it << " ";
	}
	cout << endl;
}
//使用原地置换法
class Solution {
    
    
public:
    int findRepeatNumber(vector<int> nums) 
    {
    
    
         //首先判断数组是否为空
        if(nums.size() == 0)
        {
    
    
            return -1;
        }
    	for(int i = 0;i< nums.size();i++)
        {
    
    
        	while(nums[i]!=i)
        	{
    
    
            	if(nums[i]==nums[nums[i]])
            	{
    
    
            		return nums[i];
            	}    
            	int temp = nums[nums[i]];
            	nums[nums[i]]=nums[i];
            	nums[i]=temp;       
        	}
    	}
    	return -1; 
    }
};

int main()
{
    
    
	vector<int> v1;
	int a[] = {
    
    2,3,1,0,2,5,3};
	auto length = sizeof(a)/sizeof(a[0]);
	for(int i = 0; i < length; i++)
	{
    
    
		v1.push_back(a[i]);
	}
	printVecotr(v1);
	cout  << length << endl;
	Solution S;
	auto num = S.findRepeatNumber(v1);
	cout  << num << endl;
	
	return 0;
}

输出:

0 1 1 0 2 5 3 
7
2

程序具体的实现流程:

①、i = 0, nums[0] = 2 != 0;进入交换:temp = nums[nums[0]] = 1, nums[nums[0] = nums[0] = 2,nums[0] = 1;

则数组顺序变为:{1,3,2,0,2,5,3}

②、i = 0, nums[0] = 1 != 0; 进入交换:temp = nums[nums[0]] = 3, nums[nums[0] = nums[0] = 1,nums[0] = 3;

则数组顺序变为:{3,1,2,0,2,5,3}

③、i = 0, nums[0] = 3 != 0; 进入交换:temp = nums[nums[0]] = 0, nums[nums[0] = nums[0] = 3,nums[0] = 0;

则数组顺序变为:{0,1,2,3,2,5,3}

④、此时有nums[0] = 0;nums[1] = 1;nums[2] = 2;nums[3] = 3;

⑤、i = 4, nums[4] = 2 != 4; 进入if判断:nums[4] = nums[nums[4]]) = 2,则返回2

参考链接:https://leetcode-cn.com/problems/shu-zu-zhong-zhong-fu-de-shu-zi-lcof/solution/mian-shi-ti-03-shu-zu-zhong-zhong-fu-de-shu-zi-yua/

猜你喜欢

转载自blog.csdn.net/qq_44705488/article/details/121430012