文章标题

携程笔试题:一串首尾相连的珠子(m 个),有N 种颜色(N<=10),设计一个算法,取出其中一段,要求包含所有N 中颜色,并使长度最短。并分析时间复杂度与空间复杂度。
思路:先从index=0处搜索,每检查一颗珠子,响应的颜色数量+1,如果是新的颜色则总颜色数+1.
当颜色总数为n时,找到第一个满足条件的连续序列。
1>从该序列起始处搜索,若搜索处的颜色数量不为1,则表明该串还有别的珠子有该颜色,继续往前搜索并更新该序列,起始索引位置+1.
若搜索处颜色数量为1,停止搜索。
2>比较最佳序列长与当前序列长,更新最佳序列。记录当前序列起始位置。从第一个满足条件的序列继续index++,并检查1,2条件。

package test;

public class Ctrip {
    int[] colors=new int[10];
    int colorsCount=0;
    public void find(int[] arr,int len,int colorsNeed){
        int bestStartIndex=0;
        int bestLen=len;
        int lastStartIndex=0;
        int firstFoundEnoughPearls=0;
        for(int i=0;i<arr.length;i++){
            if(colors[arr[i]]==0){
                colorsCount++;
            }
            colors[arr[i]]++;
            if(colorsCount==colorsNeed){
                firstFoundEnoughPearls=i;
                int j=lastStartIndex;
                while(colors[arr[j]]>1){
                    colors[arr[j]]--;
                    j++;
                }

                if(bestLen>(i-j+1)){
                    bestStartIndex=j;
                    bestLen=i-j+1;
                    if(bestLen==colorsNeed){
                        break;
                    }
                } 
                lastStartIndex=j;
            }
        }

        for(int i=0;i<firstFoundEnoughPearls;i++){
            if(colors[arr[i]]==0){
                colorsCount++;
            }
            colors[arr[i]]++;
            int j=lastStartIndex;
            while(colors[arr[j]]>1){
                colors[arr[j]]--;
                j++;
            }
            if(bestLen>(i-j+len+1)){
                bestLen=i-j+len+1;
                bestStartIndex=j;
                if(bestLen==colorsNeed){
                    break;
                }
            }
            lastStartIndex=j;
        }


        int offset=bestStartIndex;
        System.out.println("bestLen:"+bestLen);
        System.out.println("bestStartIndex:"+bestStartIndex);
        for(int i=0;i<bestLen;){
            System.out.print(arr[i+offset]+" ");
            i++;
            if((i+offset)>=len){
                offset=0-i;
            }
        }
    }
}
package test;

public class TestCtrip {
    public static void main(String args[]){
        int[] arr={1,2,3,3,2,1,4,2,3,2,6,4,5,2,6,2,3,4,1,2,5,2,3,4,5,6};
        int m=arr.length;
        int n=6;
        Ctrip c=new Ctrip();
        c.find(arr, m, n);
    }
}
点赞