• 无重复字符的最长子串


    给定一个字符串,请你找出其中不含有重复字符的最长子串的长度。(LeetCode题目)

    示例 1:

    输入: "abcabcbb"
    输出: 3 
    解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
    

    示例 2:

    输入: "bbbbb"
    输出: 1
    解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
    

    示例 3:

    输入: "pwwkew"
    输出: 3
    解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
    

    请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。

    方法一:暴力法

    • 思路
      • 逐个检查所有的子字符串,看它是否不含有重复的字符。
    • 算法
      • 1.为了枚举给定字符串的所有子字符串,我们需要枚举它们开始和结束的索引。假设开始和结束的索引分别为 i 和 j。那么我们有 0≤i<j≤n。因此,使用 i从 0 到 n−1以及 j从 i+1到n这两个嵌套的循环,我们可以枚举出 s 的所有子字符串。

      • 2.判断索引从i~j的字串是否包含重复的字符,若不包含则更新最大长度.

    没使用Hash表,判断字符处可使用Hash表来降低时间复杂度
    class Solution {
    public:
    	int lengthOfLongestSubstring(string s) {
    		if (s.size() == 0)
    			return 0;
    		int len = 1;
    		for (int i = 0; i < s.size(); ++i) {
    			bool f = true;
    			for (int j = i + 1; j < s.size(); ++j) {
    				if (!f) //已检测到当前重复字符,则从当前j~i+1的后续字符不必再检测
    					break;
    				for (int k = i; k < j; ++k) { //判断从i~j+1的字符是否存在重复
    					if (s[k] == s[j]) {
    						f = false;
    						break;
    					}
    				}
    				if (f)
    					len = len > (j - i + 1) ? len : (j - i + 1); //更新最大长度
    			}
    		}
    		return len;
    	}
    };
    
    

    方法二:滑动窗口

    • 算法
      • 滑动窗口是数组/字符串问题中常用的抽象概念。 窗口通常是在数组/字符串中由开始和结束索引定义的一系列元素的集合,即 [i,j)(左闭,右开)。而滑动窗口是可以将两个边界向某一方向“滑动”的窗口。使用 Hash表将字符存储在当前窗口 [i,j)(最初 j=i)中。 然后我们向右侧滑动索引 j,如果它不在 Hash表中,我们会继续滑动 j。直到 s[j] 已经存在于 Hash表中。此时,我们找到的没有重复字符的最长子字符串将会以索引 i开头。
    class Solution {
    public:
        //以字符作为key,以下表作为value
    	struct Hash_data {
    		int key, value;
    	};
    	struct Hash_table {
    		Hash_data** table;
    		int width;
    		Hash_table(int width) {
    			this->width = width;
    			table = (Hash_data**)malloc(sizeof(Hash_data*) * width);
    			memset(table, NULL, sizeof(Hash_data*) * width);
    		}
    		int addr(int key) {
    			return key % width;
    		}
    		void insert(char ch, int index) {
    			Hash_data* data = new Hash_data();
    			data->key = ch;
    			data->value = index;
    			int k = addr(ch);
    			table[k] = data;
    		}
    		void remove(char ch) {
    			int k = addr(ch);
    			table[k] = NULL;
    		}
    		bool contain(char ch) {
    			int k = addr(ch);
    			Hash_data* data = table[k];
    			if (data)
    				return true;
    			else
    				return false;
    		}
    
    	};
    	int lengthOfLongestSubstring(string s) {
    		int maxlen = 0;
    		int len = s.size();
    		int i, j;
    		i = j = 0;
    		Hash_table table(256);//初始化Hash表大小为256(char型大小)
    		while (i<len&&j<len)
    		{
    			if (table.contain(s[j])) {
    				table.remove(s[i]);
    				i++;
    			}
    			else {
    				table.insert(s[j], j);
    				maxlen = maxlen > (j - i+1) ? maxlen : (j - i+1);
    				j++;
    			}
    				
    		}
    		return maxlen;
    	}
    };
    
  • 相关阅读:
    Ubuntu20.04安装Docker
    开启企业微信H5页面调试功能
    Python实现图遍历
    Linux命令整理
    BDP数据分析之高级计算
    PowerBI之DAX
    Dundas BI 简介
    tableau的高级计算
    k8s集群创建之后coredns一直处于pending状态
    Gradle打包工具入门
  • 原文地址:https://www.cnblogs.com/HunterJ/p/11660300.html
Copyright © 2020-2023  润新知