【公司】最长子串问题-双指针解法

该博客介绍了在面对复杂产品业务时,如何处理用户程序与底层模块交互的问题。具体是一个底层模块接收到多个命令,需要找出最长的没有重复的命令序列。博主提出了双指针的方法来解决这个问题,并给出了两种不同的解决方案:一种是自己的解法,另一种是更高效的大佬解法。代码示例展示了如何找到最长不重复子串,对于信息技术领域的算法设计和实现具有参考价值。

@TOC

题目描述

产品业务较复杂时,用户程序在实现某一个特定功能时,往往需要与底层模块进行多次交互,然后组合获取的底层结果,最终完成用户功能。

实际上,一个底层模块,由于自身框架设计等原因,导致对外协议接口使用上会存在很多限制,用户程序需要严格根据底层模块的协议来进行交互。

假设存在底层模块,对外提供n种不同交互命令X,编号依次为X1,…,Xn,互不相等,

模块具有如下限制:模块先对接收到的命令进行过滤,提取序列中最长的没有重复的命令序列,如n=7,应用下发命令序列如下:

X1 X2 X3 X1 X5 X4 X2 X5 X7 X6 X1 X3 X2 X3

因此该序列中,最长的没有重复有效命令序列为 X4 X2 X5 X7 X6 X1 X3 ,即最多命令数为 7

简化上述过程,求解出 应用有效命令序列中最多命令数?

解析

题目大概就是求最长不重复子串(子串:原序列中必须连续的一段;子序列:原序列中可以不连续的一段),我这里采用的方法是双指针

https://ask.qcloudimg.com/http-save/yehe-8271427/f89b5fef965534bbe79b87bdc7cced71.png?imageView2/2/w/1620
https://ask.qcloudimg.com/http-save/yehe-8271427/c22f22b74c3de9aa916e53e5edbee783.png?imageView2/2/w/1620
https://ask.qcloudimg.com/http-save/yehe-8271427/327b2aa05c7ba564af493ded610a537b.png?imageView2/2/w/1620
https://ask.qcloudimg.com/http-save/yehe-8271427/0b810aeb48d8ab236cfa61be56b277a7.png?imageView2/2/w/1620
https://ask.qcloudimg.com/http-save/yehe-8271427/281e3e856ce039032172e904ebe462a0.png?imageView2/2/w/1620
https://ask.qcloudimg.com/http-save/yehe-8271427/2e39d2018f01d93a6bf4521356dd86b5.png?imageView2/2/w/1620

// 本蒟蒻的解法
#include <iostream>
#include <stdio.h>
#include <algorithm>

using namespace std;

int N;
// 公司题目里面没说n的取值范围
int arr[10010];
int main(){
    scanf("%d",&N);
    for(int i=0;i<N;i++) {
        scanf("%d",&arr[i]);
    }
    // s表示头指针,e表示尾指针,l记录结果
    int s=0,l=1;
    for(int e=0; e<N; e++) {
        for(int j=s; j<e; j++) {
            if(arr[j] == arr[e]){
                s = j+1;
            }
        }
        l = max(l, e-s+1);
    }
    printf("%d\n", l);
}
// 大佬的解法Orz
# include <iostream>
#include <stdio.h>

using namespace std;

int arr[100010], s[100010];
int N;

int main(){
    int l=1;
    scanf("%d", &N);
    for (int i=0,j=0; i<N; i++){
        scanf("%d",&arr[i]);
        ++ s[arr[i]];
        while (s[arr[i]] > 1) -- s[arr[j++]];
        l = max(l, i-j+1);
    }
    printf("%d\n",l);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值