每日算法(1)——数组中重复的数字

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

解法1:

数组排序,比较相邻元素是否相等。时间复杂度为 O(nlogn),空间复杂度为 O(1)。

解法2:

利用 HashSet 解决,时间复杂度为 O(n),空间复杂度也为 O(n)。

    public static boolean duplicateHashSet(int[] array) {
        if (array == null || 0 == array.length)
            return false;

        for (int i = 0; i < array.length; i++) {
            if (array[i] < 0 || array[i] > array.length - 1)
                return false;
        }

        Set<Integer> hashSet = new HashSet<>();
        for (int i = 0; i < array.length; i++) {
            if (!hashSet.add(array[i])) {
                System.out.println(array[i]);
                return true;
            }
        }

        return false;
    }

解法3:

特殊解法,遍历数组,假设第 i 个位置的数字为 j,则通过交换将 j 换到下标为 j 的位置上,直到所有数字都出现在自己对应的下表处,或发生了冲突。代码中尽管有一个两重循环,但每个数字最多只要交换两次就能找到属于它自己的位置,因此总的时间复杂度为 O(n)。所有操作都是在数组上进行的,不需要额外分配内存,因此空间复杂度为 O(1)。

    // 可输出所有重复的元素
    public static Collection duplicate(int[] array, Collection<Integer> c) {
        if (array == null || 0 == array.length)
            return null;

        for (int i = 0; i < array.length; i++) {
            if (array[i] < 0 || array[i] > array.length - 1)
                return null;
        }

        for (int i = 0; i < array.length; i++) {
            while (array[i] != i) {
                if (array[i] == array[array[i]]) {
                    System.out.println(array[i]);
                    c.add(array[i]);
                    break;
                }
                int tmp = array[i];
                array[i] = array[tmp];
                array[tmp] = tmp;
            }
        }

完整代码

import java.util.*;

public class RepeatNum {
    public static int[] array;
    public static Collection<Integer> collection;

    public static boolean duplicateHashSet(int[] array) {
        if (array == null || 0 == array.length)
            return false;

        for (int i = 0; i < array.length; i++) {
            if (array[i] < 0 || array[i] > array.length - 1)
                return false;
        }

        Set<Integer> hashSet = new HashSet<>();
        for (int i = 0; i < array.length; i++) {
            if (!hashSet.add(array[i])) {
                System.out.println(array[i]);
                return true;
            }
        }

        return false;
    }

    public static Collection duplicate(int[] array, Collection<Integer> c) {
        if (array == null || 0 == array.length)
            return null;

        for (int i = 0; i < array.length; i++) {
            if (array[i] < 0 || array[i] > array.length - 1)
                return null;
        }

        for (int i = 0; i < array.length; i++) {
            while (array[i] != i) {
                if (array[i] == array[array[i]]) {
                    System.out.println(array[i]);
                    c.add(array[i]);
                    break;
                }
                int tmp = array[i];
                array[i] = array[tmp];
                array[tmp] = tmp;
            }
        }

        return c;
    }

    public static void main(String[] args) {
        array = new int[]{2, 3, 1, 0, 2, 5, 3};
        collection = new ArrayList<>();
        collection = duplicate(array, collection);
        boolean bb = duplicateHashSet(array);
        System.out.println(collection.toString());
        System.out.println(bb);
    }
}

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 背景 一年多以前我在知乎上答了有关LeetCode的问题, 分享了一些自己做题目的经验。 张土汪:刷leetcod...
    土汪阅读 14,348评论 0 33
  • 1.把二元查找树转变成排序的双向链表 题目: 输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。 要求不...
    曲终人散Li阅读 8,627评论 0 19
  • 分享四个免费安卓市场资源进行ASO优化 一、百度手机助手 1、“官方认证”的应用 当你的APP在百度手机助手提交通...
    问媒体阅读 4,481评论 0 4
  • 每当早上闹钟一个一个的关,疯狂痴迷与床褥的缠绵,苦苦拒绝穿衣洗漱的时候,都会下决心,今晚一定要早睡!11点一定睡,...
    三哥mua阅读 3,919评论 0 0
  • 前段时间看了“前任2,备胎反击战”这部电影,虽然整体对这部电影感觉一般,但是,里面有句台词说的很对,感情这件事情,...
    525fyq阅读 1,605评论 0 1