存在重复元素

[原题链接](初级算法 - LeetBook - 力扣(LeetCode)全球极客挚爱的技术成长平台 (leetcode-cn.com))

给定一个整数数组,判断是否存在重复元素。

如果存在一值在数组中出现至少两次,函数返回 true 。如果数组中每个元素都不相同,则返回 false

题解

法一:排序

public class Solution {
    /**
     * 给定一个整数数组,判断是否存在重复元素。
     * 如果存在一值在数组中出现至少两次,函数返回 true 。如果数组中每个元素都不相同,则返回 false 。
     * 排序后,若当前元素比前一个元素大,则返回true。
     * @param nums
     * @return
     */
    public boolean containsDuplicate(int[] nums) {
        //排除数组大小为1的情况
        if(nums.length <= 1) return false;
        quickSort(nums, 0, nums.length - 1);
        for (int i = 1; i < nums.length; i++) {
            if(nums[i] == nums[i - 1]) return true;
        }
        return false;
    }

    /**
     * 快速排序
     * @param nums
     * @param left
     * @param right
     */
    private void quickSort(int[] nums, int left, int right){
        int i, j, t, temp;
        if(left > right) return;
        temp = nums[left];
        i = left;
        j = right;
        while (i != j){
            while (nums[j] >= temp && i < j) j--;
            while (nums[i] <= temp && i < j) i++;
            if (i < j){
                t = nums[i];
                nums[i] = nums[j];
                nums[j] = t;
            }
        }
        nums[left] = nums[i];
        nums[i] = temp;

        quickSort(nums, left, i - 1);
        quickSort(nums, i + 1, right);
        return;
    }
}

时间复杂度O(nlogn),空间复杂度O(1),很遗憾超时了。

4. 存在重复元素_经验分享

法二:利用Set的互异性(作弊)

public class Solution {
    /**
     * 利用Set.add()
     * @param nums
     * @return
     */
    public boolean containsDuplicate(int[] nums) {
        if (nums.length <= 1) return false;
        Set<Integer> set = new HashSet<Integer>();
        for (int i = 0; i < nums.length; i++) {
            if (!set.add(nums[i])) return true;
        }
        return false;
    }
}

4. 存在重复元素_经验分享_02

法三:桶标记

public class Solution {
    /**
     * 桶排序变种
     * 初始布尔桶内全为false,每当遇到该桶对应的值,则对该桶取反,
     * 当该桶的值由true变成false时,说明有重复值,返回true
     * @param nums
     * @return
     */
    public boolean containsDuplicate(int[] nums) {
        //数组的最大值和最小值
        int max = nums[0], min = nums[0];
        //得到数组最小值和最大值
        for (int i = 0; i < nums.length; i++) {
            if(nums[i] > max) max = nums[i];
            if(nums[i] < min) min = nums[i];
        }
        //对负数进行修正
        if (min < 0) {
            min = -min;
        }
        max = max + min;
        boolean[] bucket = new boolean[max + 1];    //默认全为false
        for (int i = 0; i < nums.length; i++) {
            //若该桶值由true变成false,说明有重复值
            if (!(bucket[nums[i] + min] = !bucket[nums[i] + min])) return true;
        }
        return false;
    }
}

时间复杂度为O(n),空间复杂度为O(?)(和数据的最大值、最小值有关)

4. 存在重复元素_经验分享_03