• 【LeetCode】287. 寻找重复数


    题目描述

    给定一个包含 n + 1 个整数的数组 nums,其数字都在 1 到 n 之间(包括 1 和 n),可知至少存在一个重复的整数。假设只有一个重复的整数,找出这个重复的数。

    示例 1:

    输入: [1,3,4,2,2]
    输出: 2
    

    示例 2:

    输入: [3,1,3,4,2]
    输出: 3
    

    说明:

    不能更改原数组(假设数组是只读的)。
    只能使用额外的 O(1) 的空间。
    时间复杂度小于 O(n^2) 。
    数组中只有一个重复的数字,但它可能不止重复出现一次。

    题解

    本题目限定了元素的取值范围"其数字都在 1 到 n 之间(包括 1 和 n)"。

    另外,“说明”里的也特别重要~

    说明:
    > 不能更改原数组(假设数组是只读的)。
    > 只能使用额外的 O(1) 的空间。
    > 时间复杂度小于 O(n^2) 。
    > 数组中只有一个重复的数字,但它可能不止重复出现一次。
    

    最后解决的思路很简单,就是使用双指针,直接看代码注释即可。

    代码

    class Solution {
        public int findDuplicate(int[] nums) {
            // 如果数组就只有两个元素,直接返回即可
            if(nums.length <= 2) { return nums[0]; }
            
            int q = 0, s = 0;
            int indexStart = 0; // indexStart用以记录起步位置
            
            // 初始化q、s应该指向[第一个index!=nums[index]的元素],不应该为0
            for(int index = 0; index < nums.length; index++) {
                if(index != nums[index]) {
                    q = index;
                    s = index;
                    indexStart = index; // 保存起步位置
                    break;
                }
            }
    
            // 快慢指针从同一位置(index)起步
            while(true) {
                // 快指针q的步长=2
                q = nums[nums[q]];
                // 慢指针s的步长=1
                s = nums[s];
                // 两指针相遇,结束第一次循环
                if(q == s) {
                    // 慢指针回到初始起步点indexStart
                    s = indexStart;
                    break;
                }
            }
    
            // 快慢指针继续一起移动,但要修改快指针的步长
            // 快慢指针再相遇的元素,即所要的结果
            while(true) {
                // 快指针q的步长=1
                q = nums[q];
                // 慢指针s的步长=1
                s = nums[s];
                // 两指针相遇,结束循环
                if(q == s) { break; }
            }
    
            return s;
        }
    }
    

    提交

    题后

    今天这“每日一题”和《【LeetCode】面试题03. 数组中重复的数字》有些类似。
    不同的是,今天这题限定了一些特别的条件,比如:

    • 不能更改原数组(假设数组是只读的)
    • 只能使用额外的 O(1) 的空间
    • **时间复杂度小于 O(n^2) **
      尤其是对复杂对的要求,这就提高了算法设计的难度。


    我想着各种优化方法,很艰难地,最后找到了这种。
    哇地一声就哭出来了,太难了/(ㄒoㄒ)/~~

  • 相关阅读:
    我在华为做敏捷测试的那些流程
    精简测试用例编写
    五步定位性能瓶颈
    敏捷软件测试--初见
    并发用户数与TPS之间的关系
    关于CSS样式的那些事_导航条菜单讲解
    关于字符串的一些简单编码题
    设置div控件居中的方法
    sqlplus登录Oracle时ORA-01017: invalid username/password; logon denied的错误
    java中的foreach输出数组中的元素
  • 原文地址:https://www.cnblogs.com/melodyjerry/p/12966784.html
Copyright © 2020-2023  润新知