Algorithm-Arrays-5 Repeat and Missing Number Array

1. 问题

You are given a read only array of n integers from 1 to n.

Each integer appears exactly once except A which appears twice and B
which is missing.

Return A and B.

Note: Your algorithm should have a linear runtime complexity. Could
you implement it without using extra memory?

Note that in your output A should precede B.

Example:

Input:[3 1 2 5 3]

Output:[3, 4]

A = 3, B = 4

给定一个数组,数组大小为n, 且该数组中存储的数据为1到n. 除了有一个重复的数字,和一个遗失的之外,每个其他数字仅仅出现一次。编写程序实现该算法。

2. 思路

可以用2个数组,大小为数组的长度,分别存储的是重复值的位置标志和遗失的值的位置索引。

public class Solution {
    // DO NOT MODIFY THE LIST
    public ArrayList<Integer> repeatedNumber(final List<Integer> a) {
        boolean repeat[] = new boolean[a.size()];
        boolean missing[] = new boolean[a.size()];
        ArrayList<Integer> result = new ArrayList<>();

        int repeatNum = 0;
        for (int val : a) {
            if (repeat[val - 1] == false)
                repeat[val - 1] = true;
            else
                repeatNum = val;
        }
        int missingNum = 0;
        for (int val : a) {
            missing[val - 1] = true;
        }
        for (int i = 0; i < a.size(); i++) {
            if (!missing[i])
                missingNum = i + 1;
        }
        result.add(repeatNum);
        result.add(missingNum);
        return result;
    }
}

3. 参考答案–另一种解法

参考答案解法:简单粗暴。首先将数组排序;然后找到重复的数字,只需便利一层循环即可得到;遗失的数字仅需通过等差数列求和公式,简单相减即可得到。

public class Solution {
    // DO NOT MODIFY THE LIST
    public ArrayList<Integer> repeatedNumber(final List<Integer> A) {

        ArrayList<Integer> res = new ArrayList<>();

        Collections.sort(A);
        int n = A.size();
        int rep = -1;
        int miss = -1;
        long sum = A.get(0);

        for (int i = 1; i < n; i++) {
            if (A.get(i).intValue() == A.get(i - 1).intValue()) {
                rep = A.get(i);
            }
            sum += A.get(i);
        }

        miss = (int) ((1L * n * (1L * n + 1)) / 2 - sum + rep);

        res.add(rep);
        res.add(miss);

        return res;

    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值