Day4 找出数组中重复的数字

最近疫情好严重,一周没出门了,今年过年也不串亲戚了,这样也很清静,安心下来学习就好了。

关于数据结构与算法,基础比较差,感觉还是比较艰辛的,一道题目需要花几个小时才能差不多掌握了。

目前感觉,学习解算法题可以分为这几个程度:

  1. 解出题目:这是最基础的,对于基础算法题,也比较容易解出来。比如这道题,找到第一个数字和后面一个一个比,然后再换第二个重复操作,直到遍历完,这种很好想,但效率是O(n^2),解的就比较蠢了。
  2. 多种方法:算法题都会有很多种解法的,这对于我就比较挑战了。比如用排序,散列表等等,基本的一些方法需要多留意了。
  3. 最优方法:这设计到方法的比较和选择了。这就很有挑战了,如何找到时/空复杂度都比较好的算法?答案提供的思路都很漂亮,但如何能想到这种思路呢?
  4. 细节部分:以上是大思路,还有很多的细节可以优化,小到一些标识符更规范的命名,各种测试用例的情况都要考虑到。比如如果出现两次以上的重复数据,答案需要只输出一次。

完成第1步半个小时就可以了,但到第2步就得一个小时以上,只分析还好,自己都实现出来时间就要更久了。完成之后的要求需要的时间就更长了,但时间就那么多。

所以目前来看每道题不要超过两个小时,边学边练,一天掌握一道题也不错了。书上的方法都要实现一遍,比较难得的先理解一下思路,然后把书上的代码一行行理解的编下来,做题多了选择方法的时候就会有印象或者有感觉了,细节部分慢慢完善。

题目部分:

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

    public static void main(String[] args) {
        int[] arr1 = {2, 1, 3, 0, 2, 5, 3}; // 有重复数字
        int[] arr2 = {0, 1, 2, 3, 4, 5, 6}; // 无重复数字
        int[] arr3 = {7};                   // 数据不合理

        duplicate3(arr1);


    }
    // 普通方法,时间效率O(n^2)
    public static void duplicate0(int[] arr) {
        for(int i = 0; i < arr.length; i++) {
            if(arr[i] < 0 || arr[i] >= arr.length) {
                System.out.println("error!");   // 无效输入测试用例
            }
            for( int j = i+1; j < arr.length; j++) {
                if(arr[i] == arr[j]){
                    System.out.println(arr[i]); // 输出重复数字
                    break;
                }
            }
        }
    }
    //排序算法,时间效率O(nlogn)
    public static void duplicate1(int[] arr) {
        quickSort(arr, 0, arr.length-1);
        int dup = -1;

        for(int i = 0; i <= arr.length-2; i++) {
            if(arr[i] < 0 || arr[i] >= arr.length) {
                System.out.println("error!");   // 无效输入测试用例
            }
            if(arr[i] == dup) {
                continue;      // 多次重复的数字只输出一次
            }
            if(arr[i] == arr[i+1]) {
                dup = arr[i];  // 记录重复数字
                System.out.println(arr[i]);  // 输出重复数字
              }
        }
    }
    public static void quickSort(int[] arr,int low,int high){ // 略 } 

    //哈希表,时间效率O(n),空间占用O(n)
    public static void duplicate2(int[] arr) {
        int[] arr0 = new int[arr.length];
        int value;
        for(int i = 0; i < arr.length; i++) {
            if(arr[i] < 0 || arr[i] >= arr.length) {
                System.out.println("error!");   // 无效输入测试用例
                return;
            }
            value = arr0[arr[i]];
            if(value == 0) {
                arr0[arr[i]] = value + 1;         // 记录新值
            }else if(value == 1) {
                arr0[arr[i]] = value + 1;
                System.out.println(arr[i]); // 输出重复值
            }
        }
    }

    // 剑指Offer解法:数字是有范围的(0~n-1),遍历时把数字交换至对应大小的下标处
    // 时间复杂度:O(n),遍历一遍,每个数字最多交换两次
    // 空间复杂度:O(1)
    public static void duplicate3(int[] arr) {
        for(int i = 0; i < arr.length; i++ ) {
            // 数据合理性检查
            if(arr[i] < 0 || arr[i] > arr.length -1) {
                System.out.println("error!");   // 无效输入测试用例
                return;
            }
            // 查找重复数据
            while(arr[i] != i) {
                if(arr[arr[i]] == arr[i]) {
                    // 位置已有元素,说明重复
                    System.out.println(arr[i]);
                    break;
                }else {
                    // 交换位置
                    int temp = arr[arr[i]];
                    arr[arr[i]] = arr[i];
                    arr[i] = temp;
                }
            }
        }
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值