美文网首页
LeetcodeT287

LeetcodeT287

作者: C调路过 | 来源:发表于2020-03-17 23:37 被阅读0次
//[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(n2) 。 
// 数组中只有一个重复的数字,但它可能不止重复出现一次。 
// 
// Related Topics 数组 双指针 二分查找


import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

public class T287 {

    public static void main(String[] args) {
        System.out.println(new T287().findDuplicate(new int[]{1,3,4,2,1}));
    }

    /**
     * 时间复杂度  排序 nlog(n) + 遍历n
     * 空间复杂度  不需要额外空间
     */
//    public int findDuplicate(int[] nums) {
//        Arrays.sort(nums);
//        for (int i = 1; i < nums.length; i++) {
//           if(nums[i] == nums[i-1]){
//               return nums[i];
//           }
//        }
//        return -1;
//    }

    /**
     * 时间复杂度  遍历n
     * 空间复杂度  因为数字就1-n 额外开一个n的数组作为映射
     *
     * @param nums
     * @return
     */
//    public int findDuplicate(int[] nums) {
//        int[] map = new int[nums.length];
//        for (int i = 0; i < nums.length; i++) {
//            if (map[nums[i]-1]>0){
//                return nums[i];
//            }
//            map[nums[i]-1]++;
//        }
//        return -1;
//    }


//    public int findDuplicate(int[] nums) {
//        // 用HashSet和HashMap没差
//        Set set = new HashSet();
//        for (int i = 0; i < nums.length; i++) {
//            if (set.contains(nums[i])) {
//                return nums[i];
//            }
//            set.add(nums[i]);
//        }
//        return -1;
//    }

    /**
     * 剑指offerP40
     * 与数组映射方法类似,节省了额外的内存开销
     */
//    public int findDuplicate(int[] nums) {
////        int i = 0;
////        while (i < nums.length) {
////
////            if (nums[i] != i + 1) {
////                if (nums[i] == nums[nums[i] - 1]) {
////                    return nums[i];
////                } else {
////                    int t = nums[i];
////                    nums[i] = nums[nums[i] - 1];
////                    nums[t - 1] = t;
////                }
////                continue;
////            }
////            i++;
////        }
////        return i;
////    }

    /**
     * 剑指OfferP43
     * 时间复杂度 二分 log(n) * 遍历 n
     * 不需要对原数组进行操作,需要几个变量的空间
     */
    public int findDuplicate(int[] nums) {

        int l = 1;
        int r = nums.length - 1;
        while (l < r) {
            int mid = (l + r) / 2;
            int c = 0;// 在 l - r 范围内的总数
            int v = 0;// 在 l - mid 范围内的数
            for (int i = 0; i < nums.length; i++) {
                if (nums[i] >= l && nums[i] <= r) {
                    c++;
                    if (nums[i] <= mid) {
                        v++;
                    }
                }
            }
            if (v * 2 > c) {
                r = mid;
            } else {
                l = mid + 1;
            }
        }
        return l;
    }
}

相关文章

网友评论

      本文标题:LeetcodeT287

      本文链接:https://www.haomeiwen.com/subject/opdfyhtx.html