您的位置:首页 > 其它

牛课堂左神算法题总结

2017-09-24 21:29 127 查看
给定一个无序整型数组arr,找到数组中未出现的最小正整数。

举例:

arr=[-1,2,3,4] 返回 1;

arr=[1,2,3,4,] 返回 5;

需求:时间复杂度为O(N),额外空间复杂度为O(1);

public static int missNum(int[] arr)
{
int l = 0;
int r = arr.length;
while(l<r){
if(arr[l]==l+1){
l++;
}else if(arr[l]<=l||arr[l]>r||arr[arr[l]-1]==arr[l]){
arr[l]=arr[--r];
}else{
swap(arr,l,arr[l]-1);
}
}
return l+1;
}


分析:

首先这个题目不能用排序 排序的最优是O(nlgn) 比O(n)大 所以只能是线性的时间 只能是遍历一次出结果

变量解释:l 表示遍历过的元素中收集到1-r中的最优情况下的值(通俗的讲就是遍历过来收集到的从小到大有序整数,比如 1,2,5,4,5…. 正好遍历到第二个5的位置的时候l中收集到了2(l=2) 所以初始化是l=0)

r表示最优情况下能收集到的(想收集到的)有序整数的最大值 所有r初始化时为arr.length;

l和r分别表示遍历过程的左右边界 相遇时遍历结束

主要出现在三个else中的三个情况下:

1.当一路顺利遍历下来时 l就一直遍历下去(所谓的顺利遍历下来就最优的情况12345….这样有序的排下去,即arr[l]=l+1)

2.三个条件 当遍历的值小于下标时即上面12545的情况 l没收集到遍历相对的有序值 即前面遍历时出现没用的值 占了一个位置 使最优下降

当遍历的值大于r值时即比最大的需要的整数都大 也没用 我们只要收集到r就已经是最优了 比r大就超出了范围 占了一个位置 使最优下降

当前一个数和第二个数重复时 也是一个废值 占了一个位置 使最优下降

出现上面三种情况r– 就是说最优下降 我们收集不到r 的情况 所有最优值在缩小

然后当arr[l]位置上的值为废值的时候把最后一个值拿过来赋给他做这个else的判断 看最后一个本来因为最优情况缩小无奈被抛弃的值是否符合我们收集的条件 如果符合也可以是l++

3.不符合2中的三个条件就说明出现在了l+1到r之间的值 但是有不是顺序出现的值 如arr[3]位置上出现7(本来应该是4)那就把这个值放到他应该在的位置 (即arr[6]的位置上去) 然后把那个位置上的值拿过来判断上面的三个else 同样如果符合条件就l++

l不断增大 r不断减小 当相遇的时候 结束 输出l+1
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: