• 算法总结之 数组中未出现的最小正整数


     给定一个无序整型数组arr,找到数组中未出现的最小正整数

    解题思路非常好,需要好好学习一下,很逻辑

     如果arr长度为N, 最优解可以做到时间复杂度O(N) 额外空间复杂度O(1)

      1、遍历arr之前生成两个变量, l  r   初始值 l=0   r=N

      2、从左到右遍历arr,arr[l]

      3、如果arr[l]=l+1 没有遍历arr[l]之前,arr已经包含的正整数范围是[1,l],此时出现了arr[l]=l+1的情况,所以arr包含的正整数范围可以扩展到[1,l+1]  即令 l++  

      4、如果arr[l]<=l  没有遍历arr[l]之前,arr在后续最优的情况下可能包含的正整数范围是[l,r],已经包含了的正整数的范围是[1,l],所以需要[l+1,r]上的数。而此时出现了arr[l]<=l,说明[l+1,r]范围上的数少了一个,所以

           arr在后续最优的情况下,可能包含的正整数范围缩小了,变为[l,r-1],此时把arr最后位置的数(arr[r-1])放在位置l上,下一步检查这个数,然后令r--,

       5、如果arr[l]>r,与上面同理的,把arr最后位置的数(arr[r-1])放在位置l上,下一步检查这个数,然后令r--

       6、如果arr[l]=arr[arr[i]-1],如果上面两个都没中,说明 arr[l]是在[l+1,r]范围上的数,而且这个数应该放在arr[l]-1位置上,可是此时发现arr[l]-1位置上的数已经是arr[l], 说明出现了两个arr[l]呀,既然在[l+1,r]上出现了         两个arr[l],重复了。那么[l+1,r]范围上的数又少了一个,所以与步骤4和5一样,把arr[r-1]放在位置l上,下一步检查,然后另r--

      7、 如果都没有中,说明发现了[l+1,r]范围上的数,并且没有重复。那么arr[l]应该放在arr[l]-1位置上,所以把l位置上的数和arr[l]-1位置上的数交换,下一步继续遍历l位置上的数

      

       最终l和r会碰撞在一起(l==r) arr已经包含的正整数范围是[1,l],

    package TT;
    
    public class Test83 {
    
        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;
        }
        
        
        
    }
  • 相关阅读:
    初谈DHCP中继原理和配置
    css3渐变之linear-gradient与-webkit-linear-gradient写法异同
    mac svn 更新到新版本1.8
    mac显示所有文件、不产生.DS_Store文件
    mac自定义安装nodejs步骤
    nodejs 80端口监听失败及NODE_PATH不起作用的问题
    一种javascript链式多重继承的方式(__proto__原型链)
    apk反编译、smali修改、回编译笔记
    启用“关闭自动根证书更新”,解决Windows系统各种卡顿的问题(Visual studio 卡、远程桌面mstsc卡、SVN卡)
    SQL查询中关于索引使用的笔记
  • 原文地址:https://www.cnblogs.com/toov5/p/7497589.html
Copyright © 2020-2023  润新知