剑指offer——字符串(Leetcode)

本文深入探讨了字符串处理的高效方法,包括空格替换和寻找最长无重复子字符串的问题。通过多种编程语言如C++, Java和Python的实现,展示了不同的算法思路,如双指针、动态规划和滚动数组等。

面试题05. 替换空格

题目
请实现一个函数,把字符串 s 中的每个空格替换成"%20"。

输入:s = “We are happy.”
输出:“We%20are%20happy.”

主要体会不同语言下的字符串替换使用。
C++:

class Solution {
public:
    string replaceSpace(string s) {
        string ans;
        for(int i = 0; i<s.size(); i++) {
            if(s[i] == ' ') {
                ans +="%20";
            }
            else    ans+=s[i];
        }
        return ans;
    }
};

java:

class Solution {
    public String replaceSpace(String s) {
        StringBuilder res = new StringBuilder();
        for(Character c : s.toCharArray())
        {
            if(c == ' ') res.append("%20");
            else res.append(c);
        }
        return res.toString();
    }
}

python:

class Solution:
    def replaceSpace(self, s: str) -> str:
        res = []
        for c in s:
            if c == ' ': res.append("%20")
            else: res.append(c)
        return "".join(res)

面试题48. 最长不含重复字符的子字符串

题目
请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度。

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

  1. 双指针
    i为左指针,j为右指针,使用map记录字符s[j]的当前位置,当遇到下一个相同字符时,更新。
class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        map<char,int> mp;
        int maxlen=0;
        int i=-1;
        for(int j=0;j<s.length();j++){
            if(mp.count(s[j])){
                i=max(i,mp[s[j]]);
            }
            maxlen=max(maxlen,j-i);
            mp[s[j]]=j;
        }   
        return maxlen;   
    }
};
  1. 动态规划
class Solution {
    const int maxn=40010;
public:
    int lengthOfLongestSubstring(string s) {
        if(s=="") return 0;
        if(s==" ") return 1;
        int dp[maxn];
        map<char,int> mp;
        for(char x='a';x<='z';x++){
            mp[x]=-1;
        }
        dp[0]=1;mp[s[0]]=0;
        int len=s.length();
        int maxlen=1;
        for(int j=1;j<len;j++){
            int i=mp[s[j]];
            dp[j]= (j-i>dp[j-1])? dp[j-1]+1 : j-i;
            mp[s[j]]=j;
            maxlen=max(maxlen,dp[j]);
        }
        return maxlen;
    }
};

滚动数组优化:

class Solution {
    const int maxn=40010;
public:
    int lengthOfLongestSubstring(string s) {
        if(s=="") return 0;
        if(s==" ") return 1;
        map<char,int> mp;
        for(char x='a';x<='z';x++){
            mp[x]=-1;
        }
        int len=s.length();
        int maxlen=1;
        int tmp=0;
        for(int j=0;j<len;j++){
            int i=mp[s[j]];
            tmp= (j-i>tmp)? tmp+1 : j-i;
            mp[s[j]]=j;
            maxlen=max(maxlen,tmp);
        }
        return maxlen;
    }
};

使用vector比使用map要快很多,一样的代码,将map转为vector,时间从48ms–>12ms.

class Solution {
    const int maxn=40010;
public:
    int lengthOfLongestSubstring(string s) {
        if(s=="") return 0;
        if(s==" ") return 1;
        vector<int> mp(255,-1);
        int len=s.length();
        int maxlen=1;
        int tmp=0;
        for(int j=0;j<len;j++){
            int i=mp[s[j]];
            tmp= (j-i>tmp)? tmp+1 : j-i;
            mp[s[j]]=j;
            maxlen=max(maxlen,tmp);
        }
        return maxlen;
    }
};
  1. 滑动窗口
class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        vector<int> arr(255,0);

        int len = s.size();
        int ans = 0;
        int left = 0;

        for(int i = 0; i < len; i++)
        {
            arr[s[i]]++;

            while(arr[s[i]] > 1 && left < i)
            {
                arr[s[left]]--;
                left++;
            }

            ans = max(ans,i - left + 1);
        }
        return ans;
    }
};
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值