zoukankan      html  css  js  c++  java
  • 【算法】剑指第二版3.数组中重复数字

    题干

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

    直觉思路

    1. 排序 O(nlogn): O(nlogn)排序+O(n)遍历查找

    2. 哈希表 O(n)+O(n)

    分析后才能得到的思路

    1. 在没有重复数字的情况下,每个位置的数字应该和下标对应相等。

    怎么想到的

    这个思路怎么想到的,暂时难以清晰描述出来,只能观察题目的特点,进行思路尝试。

    PS. 注意区分排序后的位置属于它的位置,假设没有重复,则每个数都有属于自己的位置。 如果有重复的数,则会出现2个数放到同一个位置的情况,也就发现了重复元素。

    题目分析

    [1(cur),0,1]
    cur(1)的位置不对,和位置1的元素交换 -> [0,1,1]
    cur(0)的位置正确,cur前进 -> [0,1(cur),1]
    cur(1)的位置正确,cur前进 -> [0,1,1(cur)]
    cur(1)的位置不对,交换前进行检查,发现目标位置已经有该元素,即此时的cur就是重复数字。

    代码编写思路

    基于[101]的分析:
    从描述中,可以分享有个外循环负责遍历,内部有while循环直到cur位置的元素放在了正确位置才结束,如果不在正确位置就要交换到正确位置,交换位置之前需要检查cur位置和交换位置的值是否相等,相等则找到重复,不相等则交换。

    func FindAnyDuplicates(nums []int) int {
    	// 5. 输入空检查
    	if len(nums) == 0 || nums == nil {
    		return -1
    	}
    	for _, v := range nums {
    		if v < 0 || v > len(nums)-1 { // 4.输入合理性检查 数字范围[0,n-1]
    			return -1
    		}
    	}
    	// 1. 遍历数组
    	for i, _ := range nums {
                    // 2. 内循环直到把cur位置放的就是cur值才结束
    		for nums[i] != i {
    			// 3. 如果交换的目标位置值就是cur值,说明出现重复
    			if nums[i] == nums[nums[i]] {
    				return nums[i]
    			}
    			// 3. 把当前元素交换到属于它的位置 // YC: 不是放到排序后的位置 // YC:假设数组没有重复,则cur就被交换到了排序后的位置 // TODO:在有重复元素的情况下,并不是交换到属于他的位置。比如[23344],把2交换位置2[33244],而位置2显然不是排序后2的位置,而是属于2的位置。
    			nums[i], nums[nums[i]] = nums[nums[i]], nums[i]
    		}
    	}
    	return -1
    }
    
    • 时间复杂度

    YW: 你自己拿个数组试一试就知道,这种写法,最坏情况,也就是交换两次的时候是:第一次被交换(另一个数回到自己的下标)等下一次在用到它,就该它跟别人换,就到自己数值的那个下标了。


    我本来是想用常规思路分析复杂度,先外层O(n),然后内层常数次,但是这个不太好使。
    所以2个循环一起分析,因为每个数最多交换2次就能找到对的位置,所以这2个循环整体执行交换操作的次数不超过2n,所以就是O(n)。

    速记

    每个位置的数字与其对应的下标相等

  • 相关阅读:
    windows自带摘要工具
    黑客帝国中的黑猫是什么?
    安装EdXposed提示请先从magisk manager中安装riru
    magisk和xposed和frida的区别
    awvs激活成功但是扫描失败 License problem 40
    KALI LINUX 工具大全之信息收集数字取证 Xplico (解释)
    小米机型代号
    黑客帝国高告诉我们的世界观认清自己
    web漏洞扫描器
    burpsuite中注入器的必知攻击方式
  • 原文地址:https://www.cnblogs.com/yudidi/p/12326711.html
Copyright © 2011-2022 走看看