287. 寻找重复数的几种解法

287. 寻找重复数

数组中重复数字

这题的难点就在于下面的说明了,我们先不管下面的那些说明的要求,用常规的解法来解答下上的题目。

排序思想解法

先把原来的数组进行排序,然后逐个遍历,一旦发现后一个元素和当前的元素相等,那么就返回,这就是我们找到了重复数字。但是这种思想,就不满足说明里面的,不能改变原数组,虽然时间复杂度是满足O(n^2)。

哈希思想

用个哈希集合(HashSet)来记录已经出现过的元素,一旦遍历到了元素曾经出现在集合当中,那么就返回,这就是需要寻找的重复数字。

重新排序的思想

这种思想说起来有点复杂,但是时间复杂度是最好的。
我们从头开始遍历数组,遍历到的下标为i,那么我们就分两种情况来讨论:

  1. 如果num[i]等于(i+1),就是值等于刚好等于下标那么就遍历到下一个。因为刚刚好这个就是对应的,我们就不管他了。
  2. 如果num[i]和(i+1)不等,那么就去吧下标等于(num[i] - 1)的数字和这个数字进行交换(下标为i),这样再去判断如今的这个位置上的value和index是否相等,如果不等,继续交换。交换到这个位置上的num[i]和(i+1)相等为止;或者你会找到一个数字,这个数字,那个数字在对应的位置上已经有了,那么这个就是重复的那个数字了。

Talk is cheap, show me the code.

public int findDuplicate(int[] nums) {
    if (nums.length == 0) {
        return 0;
    }
    int res = 0;
    for (int i = 0, len = nums.length; i < len; i++) {
        int temp = i + 1;
//          判断num[i]的值是不是就是放在这
        if (temp == nums[i]) {
            continue;
        } else {
//              两个不相同就进入循环,
            while (temp != nums [i]) {
                int newIndex = nums[i] - 1;
//                  如果位置上的数字和num[i]相等,那么就表示出现重复的数字,
                if (nums[newIndex] == nums[i]) {
                    return nums[i];
                }
//                    交换两个元素
                int swapTemp = nums[newIndex];
                nums[newIndex] = nums[i];
                nums[i] = swapTemp;
            }
        }
    }
    return res;
}

当然了,以上依然不是最好的解法。因为虽然时间是O(n),但是却把原来的数组变动了。

用二分思想

这里的思想有点复杂,大概的思想是这样:
我们先假设一个如果排序好的数组中,你如果取中间的数字,那么如果你的这个中间数 是要比当前的索引的坐标大的话,那么就是也就是nums[i] > i,那么就是说明那个重复的数字是在后半部分的,因为只有在后半部分有重复数字存在的时候,才会多出一个数字来,那么我们就用二分法,吧start取到中点位置,继续寻找;反之,那个重复的数字是在前半部的。
因为我们这数组是没排序的数组,那么我们根据上面的那个计数的思想,我们先取一个取值范围,如果数组里面的元素的取值在这个取值范围的元素个数,等于这个取值范围的区间,那么就表示这个取值范围内不存在重复元素,我们要取别的区间的,继续计数。

public int findDuplicateNew(int[] nums) {
    int start = 1;
    int end = nums.length;
    while (start <= end) {
//            取中值
        int middle = start + ((end - start) >> 1);
//            计算从开始值到中值区间内有多少数字。
        int tempCount = countRange(nums, start, middle);
//            如果已经区间已经缩小的到了只有一个数了,那么就可以判断在区间内的数字是不是有两个了。
        if (start == end) {
            if (tempCount > 1) {
                return start;
            } else {
                break;
            }
        }

//            区间就是 中值- 开始值 + 1。然后开始和计数比较。
        int range = middle - start + 1;
        if (tempCount > range) {
            end = middle;
        } else if (tempCount <= range) {
            start = middle + 1;
        }
    }
    return -1;
}

//    计数比较,时间复杂度为O(n)
private int countRange(int[] nums, int start, int end) {
    int count = 0;
    for (int item : nums) {
        if (item >= start && item <= end ) {
            count++;
        }
    }
    return count;
}

以上的时间复杂度是 O ( N l o g N ) O(NlogN) O(NlogN) ,二分的时间复杂度是 O ( l o g N ) O(logN) O(logN),每次计数的时间复杂度是 O ( N ) O(N) O(N)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 彭芳麟.数学物理方程的MATLAB解法与可视化PDF是一种将数学物理方程通过MATLAB编程进行求解并将结果可视化为PDF格式的方法。 MATLAB是一种强大的数值计算和科学工程编程语言,可以用于解决各种数学物理问题。彭芳麟使用MATLAB编写程序来求解各种不同的数学物理方程,如微分方程、偏微分方程、线性代数方程等。 对于给定的数学物理方程,彭芳麟首先将其离散化为一系列的差分方程或代数方程。然后,他使用MATLAB内置的数值计算方法,如欧拉法、龙格-库塔法、有限差分法等来求解这些方程。 使用MATLAB求解数学物理方程能够提供高精度的数值解,并且可以根据问题的需求进行自定义的程序设计。彭芳麟可以根据具体的问题进行数值实验,通过调整不同的参数,研究方程的性质和解的特征。 在得到数值解之后,彭芳麟将结果通过MATLAB中的绘图函数,如plot、contour、surf等进行可视化。他可以绘制曲线、等高线图和三维图等,将解的变化和特性直观地展示出来。 通过将可视化结果保存为PDF格式,彭芳麟可以将研究结果以一种易于分享和传播的方式呈现给其他人。PDF格式的文件可以在不同的设备上进行查看,并且不会改变原始的布局和格式。 总而言之,彭芳麟通过使用MATLAB解法和可视化为PDF格式,为数学物理方程的研究和应用提供了一种高效、准确且直观的方法。这种方法可以帮助研究者更好地理解和分析各种数学物理问题,并为实际应用提供有力的支持。 ### 回答2: 彭芳麟是一个科学家和数学家,他在数学物理方程的matlab解法与可视化pdf方面做出了要贡献。 首先,彭芳麟利用matlab编程语言开发了一套解决数学物理方程的工具包。这个工具包包括了许多常见的数学物理方程的解析和数值解法,可以帮助科学家和工程师们更好地理解和解决复杂的数学物理问题。通过这个工具包,用户可以输入数学物理方程的初始条件和参数,然后得到方程的解析解或数值解。这对于研究领域中的数学建模和物理实验具有要意义。 其次,彭芳麟还开发了一种将数学物理方程解析和解决结果可视化为pdf文件的方法。这个方法可以将数学物理方程的解析解或数值解以可视化形式呈现,使得用户可以更直观地理解和分析解决方案。通过这种可视化方法,科学家和工程师们可以更清晰地观察数学物理方程的特性和变化趋势,并可以更好地与实际问题相结合。 彭芳麟的matlab解法和可视化pdf方法为数学物理方程的解决提供了更方便和高效的工具,对于科学研究和工程应用具有要意义。他的工作不仅在学术界受到认可,也对许多行业的发展起到了积极的推动作用。 ### 回答3: 彭芳麟,数学物理方程的MATLAB解法与可视化PDF是一种用于解决数学物理问题的工具。MATLAB是一种强大的科学计算软件,可用于解析求解方程、进行数值计算和绘制图形。通过MATLAB,彭芳麟可以编写程序来解决数学物理方程,并使用其中的数值计算库函数来实现求解过程。 使用MATLAB解决数学物理方程的一般步骤如下: 1. 确定待解的数学物理方程。 2. 将方程转化为MATLAB可解析的形式,包括确定方程中的变量和参数。 3. 编写MATLAB程序,将方程表示为等式,并使用数值计算方法求解。 4. 运行程序,得到方程的解。 5. 根据需要,进行解的可视化,比如绘制出方程的图像、等高线图等。 使用MATLAB进行可视化时,可以使用其绘图函数对解进行可视化呈现。比如,可以使用plot函数绘制出函数曲线,使用surf函数绘制出三维曲面,使用contour函数绘制出等高线图等。通过可视化,彭芳麟可以直观地观察解的特点和变化趋势,进一步分析和理解数学物理问题。 另外,彭芳麟还可以将解和图形输出为PDF格式,以便与其他人分享。MATLAB提供了保存图形为PDF文件的函数,可以将解和图形保存为PDF文件,方便彭芳麟与其他研究者进行交流和讨论。 综上所述,MATLAB解法与可视化PDF是彭芳麟用于解决数学物理方程的工具。通过使用MATLAB编写程序求解方程,并通过可视化和保存结果为PDF文件,彭芳麟可以更方便地进行数学物理问题的研究和交流。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值