简体   繁体   English

在数组中重复数字

[英]Repeating number in an array

we are given a read only array of n integers from 1 to n. 我们获得了一个从1到n的n个整数的只读数组。 Each integer appears exactly once except A which appears twice and B which is missing. 每个整数仅出现一次,但A出现两次而B丢失。 Return A and B. I know my solution is not space efficient but i am wondering why i am getting wrong output for cases like: 返回A和B。我知道我的解决方案效率不高,但是我想知道为什么在以下情况下输出错误:

389, 299, 65, 518, 361, 103, 342, 406, 24, 79, 192, 181, 178, 205, 38, 298, 218, 143, 446, 324, 82, 41, 312, 166, 252, 59, 91, 6, 248, 395, 157, 332, 352, 57, 106, 246, 506, 261, 16, 470, 224, 228, 286, 121, 193, 241, 203, 36, 264, 234, 386, 471, 225, 466, 81, 58, 253, 468, 31, 197, 15, 282, 334, 171, 358, 209, 213, 158, 355, 243, 75, 411, 43, 485, 291, 270, 25, 100, 194, 476, 70, 402, 403, 109, 322, 421, 313, 239, 327, 238, 257, 433, 254, 328, 163, 436, 520, 437, 392, 199, 63, 482, 222, 500, 454, 84, 265, 508, 416, 141, 447, 258, 384, 138, 47, 156, 172, 319, 137, 62, 85, 154, 97, 18, 360, 244, 272, 93, 263, 262, 266, 290, 369, 357, 176, 317, 383, 333, 204, 56, 521, 502, 326, 353, 469, 455, 190, 393, 453, 314, 480, 189, 77, 129, 439, 139, 441, 443, 351, 528, 182, 101, 501, 425, 126, 231, 445, 155, 432, 418, 95, 375, 376, 60, 271, 74, 11, 419, 488, 486, 54, 460, 321, 341, 174, 408, 131, 115, 107, 134, 448, 532, 292, 289, 320, 14, 323, 61, 481, 371, 151, 385, 325, 472, 44, 335, 431, 187, 51, 88, 105, 145, 215, 122, 162, 458, 52, 496, 277, 362, 374, 26, 211, 452, 130, 346, 10, 315, 459, 92, 531, 467, 309, 34, 281, 478, 477, 136, 519, 196, 240, 12, 288, 302, 119, 356, 503, 527, 22, 27, 55, 343, 490, 127, 444, 308, 354, 278, 497, 191, 294, 117, 1, 396, 125, 148, 285, 509, 208, 382, 297, 405, 245, 5, 330, 311, 133, 274, 275, 118, 463, 504, 39, 99, 442, 337, 169, 140, 104, 373, 221, 499, 413, 124, 510, 159, 465, 80, 276, 83, 329, 524, 255, 387, 259, 397, 491, 517, 23, 4, 230, 48, 349, 412, 142, 114, 487, 381, 164, 35, 67, 498, 73, 440, 108, 226, 96, 132, 144, 207, 235, 33, 69, 128, 236, 364, 198, 475, 173, 493, 150, 90, 515, 111, 68, 232, 340, 112, 526, 492, 512, 495, 429, 146, 336, 17, 350, 251, 7, 184, 76, 380, 359, 293, 19, 49, 345, 227, 212, 430, 89, 474, 279, 201, 398, 347, 273, 37, 185, 177, 102, 304, 295, 422, 94, 426, 514, 116, 183, 180, 494, 42, 305, 152, 390, 30, 247, 451, 32, 388, 331, 78, 424, 368, 394, 188, 306, 449, 8, 214, 120, 179, 280, 511, 409, 338, 153, 507, 370, 461, 217, 161, 483, 147, 242, 86, 417, 268, 71, 462, 420, 167, 513, 379, 307, 522, 435, 113, 296, 457, 525, 45, 529, 423, 427, 2, 438, 64, 316, 46, 40, 13, 516, 367, 233, 110, 318, 250, 283, 216, 186, 310, 237, 377, 365, 175, 479, 378, 66, 414, 473, 165, 210, 50, 348, 372, 363, 339, 20, 168, 284, 415, 505, 206, 53, 223, 434, 202, 123, 399, 400, 135, 269, 428, 219, 456, 28, 464, 267, 489, 98, 391, 195, 366, 300, 484, 533, 229, 213, 149, 160, 256, 303, 530, 301, 29, 404, 344, 401, 220, 287, 9, 407, 170, 450, 523, 249, 72, 410, 3, 21, 200, 260

Expected Output: 预期产量:

213 87

Actual Output : 实际输出:

213 3

Java Code What I have Tried so far 到目前为止我尝试过的Java代码

public class Solution {
    // DO NOT MODIFY THE LIST
    public ArrayList<Integer> repeatedNumber(final List<Integer> a) {
        int n=a.size();
        int rep=0,b=0;
        int[] arr= new int[n+1];
        for(int i=0;i<n+1;i++) //value i is at index i
            arr[i]=i;
        arr[0]=-1;
        for(int val : a)
        {
            if(arr[val]!=-1)
                arr[val]=-1;
            else
            {
                rep=val;
                break;
            }
        }
        for(int i=0; i<n+1; i++)
        {
            if(arr[i]!=-1)
            {
                b=i;
                break;
            }
        }
        ArrayList<Integer> ans = new ArrayList<Integer>();
        ans.add(rep);
        ans.add(b);
        return ans;
    }
}

You find a mistake like this by reasoning that you need one complete pass over the array to detect a missing value. 您发现这样的错误是因为您需要对数组进行一次完整的遍历才能检测到缺失值。 You may stop earlier for the duplicate. 您可以更早停止复制。

for(int val : a){
    if(arr[val]!=-1){
        arr[val]=-1;
    } else {
        rep=val;
        ///////////////// Omit:      break;
    }
}

Later Basically the same idea but using a bit more of Java, making it shorter: 后来基本上是相同的想法,但使用了更多的Java,使其更短:

int dup = 0;
int abs = 0;
BitSet present = new BitSet( a.size() + 1 );
for( int x: a ){
    if( present.get( x ) ){
        dup = x;
    } else {
        present.set( x );
    }
}
abs = present.nextClearBit( 1 );

If you may modify the original array (or list), you can avoid using some extra storage: 如果可以修改原始数组(或列表),则可以避免使用一些额外的存储空间:

int dup = 0;
int abs = 0;
for( int i = 0; i < a.length; ++i ){
    if( a[i] <= 0 ) continue;
    int val = a[i];
    a[i] = 0;
    while( true ){
        if( a[val-1] == -val ){
            dup = val;
            break;
        } else {
            int h = a[val-1];
            a[val-1] = -val;
            if( h == 0 ) break;
            val = h;
        }
    }
}
for( int i = 0; i < a.length; ++i ){
    if( a[i] >= 0 ){
         abs = i+1;
         break;
    }
}

I would begin by using List.toArray(T[]) to get an array, sorting the array and then iterating the sorted array once. 我将首先使用List.toArray(T[])获得一个数组,对该数组进行排序 ,然后对已排序的数组进行一次迭代 Something like, 就像是,

public ArrayList<Integer> repeatedNumber(final List<Integer> a) {
    Integer[] arr = a.toArray(new Integer[0]);
    Arrays.sort(arr);
    Integer[] r = new Integer[2];
    for (int i = 1; i < arr.length; i++) {
        int prev = arr[i - 1];
        if (prev == arr[i]) {
            r[0] = prev;
        } else if (prev != arr[i] - 1) {
            r[1] = prev + 1;
        }
    }
    return new ArrayList<Integer>(Arrays.asList(r));
}

which I tested with your input and got (as requested) 我根据您的输入进行了测试并得到了(按要求)

[213, 87]

Here is a solution that doesn't alter the original list and finds the missing one using only maths. 这是一种解决方案,不会更改原始列表,仅使用数学即可找到丢失的列表。

public static void main(String[] args) {
    find(new int[]{389, 299, 65, 518, 361, 103, 342, 406, 24, 79, 192, 181, 178, 205, 38, 298, 218, 143, 446, 324, 82, 41, 312, 166, 252, 59, 91, 6, 248, 395, 157, 332, 352, 57, 106, 246, 506, 261, 16, 470, 224, 228, 286, 121, 193, 241, 203, 36, 264, 234, 386, 471, 225, 466, 81, 58, 253, 468, 31, 197, 15, 282, 334, 171, 358, 209, 213, 158, 355, 243, 75, 411, 43, 485, 291, 270, 25, 100, 194, 476, 70, 402, 403, 109, 322, 421, 313, 239, 327, 238, 257, 433, 254, 328, 163, 436, 520, 437, 392, 199, 63, 482, 222, 500, 454, 84, 265, 508, 416, 141, 447, 258, 384, 138, 47, 156, 172, 319, 137, 62, 85, 154, 97, 18, 360, 244, 272, 93, 263, 262, 266, 290, 369, 357, 176, 317, 383, 333, 204, 56, 521, 502, 326, 353, 469, 455, 190, 393, 453, 314, 480, 189, 77, 129, 439, 139, 441, 443, 351, 528, 182, 101, 501, 425, 126, 231, 445, 155, 432, 418, 95, 375, 376, 60, 271, 74, 11, 419, 488, 486, 54, 460, 321, 341, 174, 408, 131, 115, 107, 134, 448, 532, 292, 289, 320, 14, 323, 61, 481, 371, 151, 385, 325, 472, 44, 335, 431, 187, 51, 88, 105, 145, 215, 122, 162, 458, 52, 496, 277, 362, 374, 26, 211, 452, 130, 346, 10, 315, 459, 92, 531, 467, 309, 34, 281, 478, 477, 136, 519, 196, 240, 12, 288, 302, 119, 356, 503, 527, 22, 27, 55, 343, 490, 127, 444, 308, 354, 278, 497, 191, 294, 117, 1, 396, 125, 148, 285, 509, 208, 382, 297, 405, 245, 5, 330, 311, 133, 274, 275, 118, 463, 504, 39, 99, 442, 337, 169, 140, 104, 373, 221, 499, 413, 124, 510, 159, 465, 80, 276, 83, 329, 524, 255, 387, 259, 397, 491, 517, 23, 4, 230, 48, 349, 412, 142, 114, 487, 381, 164, 35, 67, 498, 73, 440, 108, 226, 96, 132, 144, 207, 235, 33, 69, 128, 236, 364, 198, 475, 173, 493, 150, 90, 515, 111, 68, 232, 340, 112, 526, 492, 512, 495, 429, 146, 336, 17, 350, 251, 7, 184, 76, 380, 359, 293, 19, 49, 345, 227, 212, 430, 89, 474, 279, 201, 398, 347, 273, 37, 185, 177, 102, 304, 295, 422, 94, 426, 514, 116, 183, 180, 494, 42, 305, 152, 390, 30, 247, 451, 32, 388, 331, 78, 424, 368, 394, 188, 306, 449, 8, 214, 120, 179, 280, 511, 409, 338, 153, 507, 370, 461, 217, 161, 483, 147, 242, 86, 417, 268, 71, 462, 420, 167, 513, 379, 307, 522, 435, 113, 296, 457, 525, 45, 529, 423, 427, 2, 438, 64, 316, 46, 40, 13, 516, 367, 233, 110, 318, 250, 283, 216, 186, 310, 237, 377, 365, 175, 479, 378, 66, 414, 473, 165, 210, 50, 348, 372, 363, 339, 20, 168, 284, 415, 505, 206, 53, 223, 434, 202, 123, 399, 400, 135, 269, 428, 219, 456, 28, 464, 267, 489, 98, 391, 195, 366, 300, 484, 533, 229, 213, 149, 160, 256, 303, 530, 301, 29, 404, 344, 401, 220, 287, 9, 407, 170, 450, 523, 249, 72, 410, 3, 21, 200, 260});
}

public static void find(int[] numbers){
    int sum = 0;
    int duplicate = -1;

    for (int i = 0; i < numbers.length; i++) {
        sum += numbers[i];

        if(duplicate == -1) {
            for (int j = i + 1; j < numbers.length; j++) {
                if(numbers[i] == numbers[j]){
                    duplicate = numbers[i];
                }
            }
        }
    }

    int missing = triangle(numbers.length) - (sum - duplicate);

    System.out.println(duplicate + " " + missing);
}

public static int triangle(int amount) {
    return (int) ((Math.pow(amount, 2) + amount) / 2);
}

I would suggest a better approach to do this. 我建议一种更好的方法来做到这一点。 Here is logical steps that you need to follow. 这是您需要遵循的逻辑步骤。

I am explaining with an Example 我用一个例子解释

ex:- incorrect Array => {20,30,40,40} and Correct Array => {20,30,40,60} 例如:-错误的数组=> {20,30,40,40}和正确的数组=> {20,30,40,60}

  1. First Calculate Sum of correct Array and incorrect Array. 首先计算正确数组和错误数组的总和。

incorrect Array sum => 130 and Correct Array => 150 . 不正确的数组和=> 130和正确的数组=> 150

  1. Calculate the difference between the sum of these two Arrays. 计算这两个数组sum之间的差。

Difference will be -20 (Negative). 差异为-20 (负)。

  1. Then Find the Integer value which is Repeated. 然后找到重复的Integer数值。

Using loop Iteration find out the Number which is getting Repeated From Incorrect Array. 使用循环迭代找出Repeated 正确的数组开始Repeated的数字。 So Repeated Number will be 40 . 因此重复编号将为40

  1. Now Substract this Repeated Number with Difference You Found (Between the two Sum) . 现在,用发现的差值Substract此重复数(两个和)

(-20)-(-40) = -60 You Got Your Missing Number . (-20)-(-40) = -60您有丢失的号码。

  1. Finally You will got your Missing Number in Negative. 最终,您将得到负数的丢失号码。 it is more efficient way to do this. 这是一种更有效的方法。

Note :- If you Iterate throughout one Incorrect array (n) in (n*n) in Nested Loops and again in Nested Loop Iterate throughout Correct array (n) in (n*n) So, Total will be (n*n*n*n) . : -如果您迭代整个一个不正确的阵列(n)(n*n)在嵌套循环和再嵌套循环迭代整个正确阵列(n)(n*n)所以,道达尔将是(n*n*n*n) Its very hectic actually. 实际上非常忙碌。 In Solution which is given by me will max upto ((n*n)+n+n) . 在我给定的解决方案中,最大可达((n*n)+n+n) So Definitely 所以绝对

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM