Leetcode->3 无重复字符的最长子串

这篇博客探讨了LeetCode第3题——找到无重复字符的最长子串。作者提供了两种解决方案,包括暴力法和滑动窗口法。在暴力法中,通过遍历所有子字符串并检查唯一性来找到答案。而在滑动窗口法中,利用unordered_set实现了更高效的求解,介绍了unordered_set的count函数来判断元素是否存在。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目

在这里插入图片描述

算法思路及代码实现

方法一:暴力法
假设我们有一个函数 bool allUnique(string substring) ,如果子字符串中的字符都是唯一的,它会返回true,否则会返回false。 我们可以遍历给定字符串 s 的所有可能的子字符串并调用函数 allUnique。 如果事实证明返回值为true,那么我们将会更新无重复字符子串的最大长度的答案。
为了枚举给定字符串的所有子字符串,我们需要枚举它们开始和结束的索引。假设开始和结束的索引分别为 ii 和 j。那么我们有 0≤i<j≤n (这里的结束索引 j 是按惯例排除的)。因此,使用 ii 从0到 n - 1以及 j 从 i+1到 n 这两个嵌套的循环,我们可以枚举出 s 的所有子字符串。

#include <iostream>
#include <string>
#include <map>
using namespace std;

class Solution{
public:
		int lengthOfLongestSubstring(string s){
				int ans = 0;
				//遍历所有无重复字符的子串
				for(int i = 0; i<s.size(); i++)
					for(int j=i+1; j<=s.size(); j++){ 
						if(allUnique(s,i,j))
								ans = max(ans,j-i); //保存最长子串的长度
					}
				return ans;
		}
		bool allUnique(string s, int begin, int end){
				map<char,int> hash;
				for(int i=begin; i<end; i++){
					if(hash.find(s[i])!=hash.end())
							return false; //存在重复字符则返回false
					hash[s[i]]=i;
				}
				return true;
		}
};

int main()
{
    Solution longstring;
    string s1 = "pwwkew";
    cout << longstring.lengthOfLongestSubstring(s1) << endl;
    //system("pause");
    return 0;
}

方法二:滑动窗口
在这里插入图片描述

#include <iostream>
#include <string>
#include <unordered_set>
using namespace std;

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        // 哈希集合,记录每个字符是否出现过
        unordered_set<char> occ;
        int n = s.size();
        // 右指针,初始值为 -1,相当于我们在字符串的左边界的左侧,还没有开始移动
        int rk = -1, ans = 0;
        // 枚举左指针的位置,初始值隐性地表示为 -1
        for (int i = 0; i < n; ++i) {
            if (i != 0) {
                // 左指针向右移动一格,移除一个字符
                occ.erase(s[i - 1]);
            }
            while (rk + 1 < n && !occ.count(s[rk + 1])) {
                // 不断地移动右指针
                occ.insert(s[rk + 1]);
                ++rk;
            }
            // 第 i 到 rk 个字符是一个极长的无重复字符子串
            ans = max(ans, rk - i + 1);
        }
        return ans;
    }
};

int main()
{
    Solution longstring;
    string s1 = "pwwkew";
    cout << longstring.lengthOfLongestSubstring(s1) << endl;
    //system("pause");
    return 0;
}

小记

1) unordered_set的介绍

1、无序集是一种容器,它以不特定的顺序存储惟一的元素,并允许根据元素的值快速检索单个元素。
2、在unordered_set中,元素的值同时是唯一标识它的键。键是不可变的,只可增删,不可修改
3、在内部,unordered_set中的元素没有按照任何特定的顺序排序,而是根据它们的散列值组织成桶,从而允许通过它们的值直接快速访问单个元素(平均时间复杂度为常数)4、unordered_set容器比set容器更快地通过它们的键访问单个元素,尽管它们在元素子集的范围迭代中通常效率较低。
5、容器中的迭代器至少是前向迭代器。

2)unordered_set的count
此函数接受单个参数element 。表示容器中是否存在需要检查的元素。
如果元素存在于容器中,则此函数返回1,否则返回0。
示例:

#include<cstdio>
#include<iostream>
#include<unordered_set> 
using namespace std;
int main(){
    unordered_set<int> us;
    us.insert(1);
    us.insert(2);
    us.insert(3);
    cout<<us.count(3)<<endl;//存在,返回1
    cout<<us.count(6)<<endl;//不存在,返回0
    return 0;
}
世界地图矢量数据可以通过多种网站进行下载。以下是一些提供免费下载世界地图矢量数据的网站: 1. Open Street Map (https://www.openstreetmap.org/): 这个网站可以根据输入的经纬度或手动选定范围来导出目标区域的矢量图。导出的数据格式为osm格式,但只支持矩形范围的地图下载。 2. Geofabrik (http://download.geofabrik.de/): Geofabrik提供按洲际和国家快速下载全国范围的地图数据数据格式支持shape文件格式,包含多个独立图层,如道路、建筑、水域、交通、土地利用分类、自然景观等。数据每天更新一次。 3. bbbike (https://download.bbbike.org/osm/): bbbike提供全球主要的200多个城市的地图数据下载,也可以按照bbox进行下载。该网站还提供全球数据数据格式种类齐全,包括geojson、shp等。 4. GADM (https://gadm.org/index.html): GADM提供按国家或全球下载地图数据的服务。该网站提供多种格式的数据下载。 5. L7 AntV (https://l7.antv.antgroup.com/custom/tools/worldmap): L7 AntV是一个提供标准世界地图矢量数据免费下载的网站。支持多种数据格式下载,包括GeoJSON、KML、JSON、TopJSON、CSV和高清SVG格式等。可以下载中国省、市、县的矢量边界和世界各个国家的矢量边界数据。 以上这些网站都提供了世界地图矢量数据免费下载服务,你可以根据自己的需求选择合适的网站进行下载
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值