剑指offer | 数组中重复的数字(基于交换 C++)

题目描述

原题链接

在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是第一个重复的数字2。

算法

(基于交换) O ( n ) O(n)
相似题 LeetCode 41.第一个缺失的正数

  • 遍历数组,把元素i放到下标为i的位置上,如果下标为i的位置上元素值不是i,那就把当前位置和下标为i的数进行交换,那么i就到了正确的位置,否则就继续往下遍历数组
  • 再遍历一次数组,如果元素i和它的下标不相等,说明元素i就是重复的元素了,此题我们通过指针返回其中一个重复元素就可以了

核心代码

for (int i = 0; i < length; i ++) {
	while(numbers[numbers[i]] != numbers[i]) {
		swap(numbers[i], numbers[numbers[i]]);
	}
}

详细解释

  下标:0 1 2 3 4
  数组:2 3 4 4 1
  
遍历数组
  i = 0时
  nums[0] = 2,2应该到下标为2的位置,所以和4交换
  交换后:4 3 2 4 1
  继续看换过来后nums[0] = 4是否在合适的位置,4应该到下标为4的位置,所以和1交换
  交换后: 1 3 2 4 4
  同理我们继续把13交换
  交换后: 3 1 2 4 4
  然后继续把34交换
  交换后: 4 1 2 3 4
  注意:此时nums[0] = 4,已经不需要放到下标为4的位置了,因为已经有个4放在那了
  	   因此i = 0这种情况结束
  
  i = 1时
  继续上面的过程
  ...
  ...

时间复杂度是 O ( n ) O(n) ,空间复杂度是 O ( 1 ) O(1)

C++代码

class Solution {
public:
    // Parameters:
    //        numbers:     an array of integers
    //        length:      the length of array numbers
    //        duplication: (Output) the duplicated number in the array number
    // Return value:       true if the input is valid, and there are some duplications in the array number
    //                     otherwise false
    bool duplicate(int numbers[], int length, int* duplication) {
        // Judge if the input is valid
        for (int i = 0; i < length; i ++) {
            if(numbers[i] < 0 || numbers[i] > length - 1)  return false;
        }
        
        // Make the element in the right position
        // Such as element 3 should in index 3
        for (int i = 0; i < length; i ++) {
            while(numbers[numbers[i]] != numbers[i]) swap(numbers[i], numbers[numbers[i]]);
        }
        
        // return a duplicate number by reference (point)
        for (int i = 0; i < length; i ++) {
            if (numbers[i] != i) {
                *duplication = numbers[i];
                return true;
            }
        }
    }
};

其他方法:

  • 排序:时间复杂度是 O ( n l o g n ) O(nlogn) ,空间复杂度是 O ( 1 ) O(1)
  • 创建一个新数组:时间复杂度是 O ( n ) O(n) ,空间复杂度是 O ( n ) O(n)

写在最后:我的博客主要是对计算机领域所学知识的总结、回顾和思考,把每篇博客写得通俗易懂是我的目标,分享技术和知识是一种快乐 ,非常欢迎大家和我一起交流学习,有任何问题都可以在评论区留言,也期待与您的深入交流(^∀^●)

发布了239 篇原创文章 · 获赞 80 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/qq_43827595/article/details/104255732
今日推荐