Array Contains Performance

后端 未结 4 1388
遇见更好的自我
遇见更好的自我 2021-01-24 18:32

I have a program which works with arrays and at some point I have to check if a lsit of values are inside an array, the function that does this takes about 70% of the program CP

4条回答
  •  盖世英雄少女心
    2021-01-24 18:47

    You're wasting a lot of work by doing a linear scan for every number throughout the array. What you should instead do is walk the array once and start observing the last number you've seen. If you see any gaps, return false. If you reach the end of the array, return true. This is O(N) instead of O(N^2) like you have it now.

    Like so:

    public static bool AreAllNumbersGenerated(int[] row)
    {
        var last = 0;
        return row.Aggregate(true, (l, r) => l && r == last++);
    }
    

    You can make some additional optimizations that won't affect your big-O complexity, e.g. using a proper loop and early-exiting.

    EDIT: I'm assuming here that you're expecting the items to occur sequentially. If this isn't the case, you can easily convert the array to a structure with ~O(1) lookups in O(N), then do the check in O(N) as well. For large input, this is still better than your O(N^2) approach above

    Like so:

    public static bool AreAllNumbersGenerated2(int[] row)
    {
        var available = row.ToDictionary(x => x);
        return Enumerable.Range(0, row.Length).All(i => available.ContainsKey(i));
    }
    

    EDIT: From what I'm seeing in the comments it looks like the goal of this code is to populate an array with a contiguous sequence of numbers in a random order. I didn't realize that was the goal, and if that is the case, shuffling is certainly better than reattempting to generate over and over. But what is even better than generating the array then shuffling (again, for sufficiently large input) is to simply generate the array by assigning each number to a randomly sampled index without substitution. Not as easy to LINQ out, but you can figure it out.

提交回复
热议问题