求字符串中包含唯一字符的最长子串

23 篇文章 0 订阅

给你一个字符串,找到只包含唯一字符的最长子串。

Given a string, find the longest sub sequence which contains only unique characters.

维护两个指针,左指针和右指针。同时用一个hash表存储左右指针之间的字符以及字符出现的位置。初始化的时候:left = 0,right = 0.右指针不断的前移,同时将所指的字符插入hash表中,直到遇到了重复字符,设为c。使用hash表找出c的位置,移动左指针并且将遇到的字符在hash表中的value清零,直到越过字符c的位置(保证了指针left和right之间的字符串的每一个字符都是唯一的)。然后重复增加right的值。同时不断的记录最长的字串。当右指针到达字符串末尾时完成整个遍历过程。

Maintain two pointers, left and right. Also maintain a hashtable of the current characters between left and right, and the position at which they appear. Initially left = 0, right = 0.

Keep incremementing right and inserting characters into the hash, till you see a duplicate char, say c. Find out where c already is in the window (using the hashtable itself), and reset the left pointer to be just past that (don't forget to delete those chars from the hash). Now continue incrementing the right pointer. Keep track of the maximum window. When right hits the end of the string, you are done.


#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int find_lseq(char *str)
{//m用来记录left指针的最终位置 hahs表用来记录字符//的位置
        char hash[128],*l,*r,*m;
//初始位置为0 最长串的长度为0
        int pos=0,max=0;
//初始化hash表
        memset(hash,-1,sizeof(hash));
//初始化left right指针
        l=r=str;
//right指针指向尾端时结束操作
        while(*r != '\0'){
//找到重复的字符 left指针移动并且将遇到的字符对应
//字符的hash值设置为-1 left指针越过重复的字符的位
//置
                if(hash[*r] >= 0){
                        while(l < str+hash[*r])
                                hash[*l++]=-1;
                        l++;
                }

                hash[*r]=pos++;
                ++r;
//左右指针之间的串的长度大于max时更新max 和 m
                if(r-l > max){
                        max=r-l;
                        m=l;
                }
        }
//根据串的长度和m指针输出字符串
        while(max--) printf("%c",*m++);
        putchar('\n');

        return(0);
}

int main(int argc, char *argv[])
{
        if(argc != 2)
                exit(1);

        find_lseq(argv[1]);
        exit(0);
}






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值