基数排序的一个应用

题目:给定一个无序的整数数组,怎么找到第一个大于0,并且不在此数组的整数。比如[1,2,0]返回3,[3,4,-1,1]返回2,[1, 5, 3, 4, 2]返回6,[100, 3, 2, 1, 6,8, 5]返回4。要求使用O(1)空间和O(n)时间。

思路:时间复杂度确切的说是O(2N)(循环部分),去掉常亮就是O(N)

代码如下:

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int Calculate(vector<int> arr)
{
    int l = arr.size();
    int i=0;
    while (i < l) 
    {
        if (arr[i]-1 == i) {
            ++i;
        }
        // 这个判定式的意思:当前的值大于位置的INDEX值,
        // 并且当前值小于当前最大的INDEX值, 
        // 并且与被交换的位置的值不相等
        else if (arr[i]-1 > i && arr[i]-1 < l && arr[i] != arr[arr[i]-1]) {
            swap(arr[i], arr[arr[i]-1]);
        }
        else {
            swap(arr[i], arr[l-1]);
            --l;
        }
    }

    return i+1;
}


int main(int argc, char ** argv) 
{
    vector<int> arr = {1,2};

    cout << Calculate(arr) << endl;
}

该算法的核心思想是,首先,第一个大于0的数并且不再数组中,那么该数一定是小于等于数组的长度,所以对于数组中的每个数,只要该数小于数组的长度,那么就归位(恢复到该数-1的下表位置), 使用Python的解法如下:

def Calculate(l):
    len_l = len(l)
    for idx, item in enumerate(l):
        if item <= len_l and item > 0:
            l[item - 1], l[idx] = item, l[item - 1]

    for idx, item in enumerate(l):
        if item <= len_l and item > 0:
            l[item - 1], l[idx] = item, l[item - 1]

    rt = len_l
    for idx, item in enumerate(l):
        if idx + 1 != item:
            rt = idx + 1
            break

    return rt

if __name__ == '__main__':
    l = [1, 5, 3, 4, 2]

    print(Calculate(l))
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容