zoukankan      html  css  js  c++  java
  • m个珠子共n种颜色,找出包含n种颜色的最短连续片段

    原题目:

    有一串的珠子(首尾不相连),共有m个,每一个珠子有一种颜色,并且颜色的总数不超过n(n<=10),求连续的珠子的颜色总数为n时,长度最小的区间。


    题目分析:

    一 、暴力搜索

        1、最简单的方法---暴力搜索,逐个扫描第i个位置开始包含n中颜色最短区间,时间复杂度为O(m^2) 。

        2、从i开始扫描,每出现一种新的颜色,计数+1 ,当计数=n时候,结束,此时即为i开始的最短区间 。

    二 、

       1、扫描一遍数组m,计算出每种颜色在数组m中下一次出现的位置,存在数据nextColor[m]中 (每种颜色的最后一个元素的下一个位置记为-1 ,在后面的程序中需要特殊处理)。

       2、从0位置开始扫描数组m,找出第一个包含所有颜色的区间,此时的开始位置即为beginTag (此时是0),结束位置记为endTag 。

       3、对beginTag进行操作:如果beginTag位置的颜色的下一个颜色nextColor[beginTag]<=endTag ,则将beginTag++ ,重复此步骤,直到nextColor[beginTag]>endTag  或者 beginTag==endTag ,此时beginTag---->endTag即为以endTag结束但包含所有颜色的最小区间 。

        4、endTag后移一步,然后重复步骤3  。

        5、重复步骤4 ,直到endTag=m.length-1 。

         6、此时可以得到所有元素结尾的最短区间的长度,选取一个最小的 。

    代码如下:

    package ddc.test.com;
    
    public class MNSelectTestMain {
    
        /**
         * @param args
         */
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            int data[]={0,1,2,3,4,4,5,4,2,3,1,0,2,3};
            getSubAll(data,6);
    
        }
        public static int[] getSubAll(int[] colorArray,int colorLength){
            for(int color:colorArray){
                if(color>=colorLength)
                    throw new RuntimeException("color error!!");
            }
            int[] least=new int[colorArray.length];
            
            int[] nextColor=new int[colorArray.length];
            for(int i=0;i<nextColor.length;i++)
                nextColor[i]= -1;
            int[] colorCounter=new int[colorLength];
            int[] colorTmp=new int[colorLength];
            for(int i=0;i<colorTmp.length;i++)
                colorTmp[i]= -1;
            
            for(int i=colorArray.length-1;i>=0;i--){
                nextColor[i]=colorTmp[colorArray[i]];
                colorTmp[colorArray[i]]=i;
            }
            int hasColor=0 ;  //已经发现的颜色总数
            int beginTag=0 ,endTag =0;
            //找到第一个包含所有颜色的结束点
            while(endTag <colorArray.length){
                if(colorCounter[colorArray[endTag]]==0){
                    hasColor++;
                    colorCounter[colorArray[endTag]]++;
                }
                if(hasColor==colorLength)
                    break;
                endTag++;
            }
            //结束点逐步后移,然后找到以endTag为结束点的最短区间
            while(endTag<colorArray.length){
                if(nextColor[beginTag]>=0&&nextColor[beginTag]<=endTag){
                    beginTag++;
                    continue;
                }
                least[endTag]=endTag-beginTag+1;
                endTag++;
            }
            //打印
            for(int tt:least)
                System.out.print(tt+" ");
            System.out.println();
            for(int tt:colorArray)
                System.out.print(tt+" ");
            return colorArray;
        }
    }
  • 相关阅读:
    ubuntu下安装flash
    PHPMailer邮件发送
    PHP制作简单分页(从数据库读取记录)
    windows下安装PHP环境
    捕获浏览器关闭,刷新事件
    ubuntu下安装wps
    用PHP制作一个简单的验证码
    一个PHP程序员应该掌握的10项技能!
    爬虫框架之scrapy
    Android杂谈禁止TimePicker控件通过keyboard输入
  • 原文地址:https://www.cnblogs.com/serendipity/p/2528545.html
Copyright © 2011-2022 走看看