数据结构算法之字符串

1.理论部分

1. 串的定义与操作

  1. 定义:串(string)是由零个或多个字符组成的有限序列,又名字符串,记为S=”a0a1…an”;串是一种特殊的线性表;
  2. 串操作:(1)获取串的长度
    (2)获取或设置指定索引处的字符
    (3)在指定位置插入子串
    (4)在指定位置移除给定长度的子串
    (5)在指定位置取子串
    (6)当前串的拷贝
    (7)串连接
    (8)串的匹配

2. 串的存储与实现

同理:串的存储分为两种:顺序存储和链式存储
顺序存储:char类型的数组。由于数组是定长的,就存在一个预定义的最大串长度,它规定在串值后面加一个不计入串长度的结束符,比如’\0’来表示串值的终结。
链式存储:SlinkList (浪费存储空间);

2.练习部分

2.1 无重复字符的最长子串

代码实现:

class Solution:
    """
    :type s: str
    :rtype: int
    """
    def lengthOfLongestSubstring(self, s):
        l = 0
        r = 0
        maxLength = 0
        s_len = len(s)
        usedChar = [0] * 256 #通过符号表记录符号出现次数
        while l < s_len:
            if r < s_len and usedChar[ord(s[r])] == 0:
                usedChar[ord(s[r])] += 1
                r += 1
            else:
                usedChar[ord(s[l])] -= 1
                l += 1

            maxLength = max(maxLength, r - l)

        return maxLength

2.2 串联所有单词的子串

代码实现:

class Solution {
public:
    vector<int> findSubstring(string s, vector<string>& words) {
        if (s.empty() || words.empty()) return {};
        vector<int> res;
        int n = s.size(), cnt = words.size(), len = words[0].size();
        unordered_map<string, int> m1;
        for (string w : words) ++m1[w];
        for (int i = 0; i < len; ++i) {
            int left = i, count = 0;
            unordered_map<string, int> m2;
            for (int j = i; j <= n - len; j += len) {
                string t = s.substr(j, len);
                if (m1.count(t)) {
                    ++m2[t];
                    if (m2[t] <= m1[t]) {
                        ++count;
                    } else {
                        while (m2[t] > m1[t]) {
                            string t1 = s.substr(left, len);
                            --m2[t1];
                            if (m2[t1] < m1[t1]) --count;
                            left += len;
                        }
                    }
                    if (count == cnt) {
                        res.push_back(left);
                        --m2[s.substr(left, len)];
                        --count;
                        left += len;
                    }
                } else {
                    m2.clear();
                    count = 0;
                    left = j + len;
                }
            }
        }
        return res;
    }
};

2.3 替换子串得到平衡字符串

代码实现:

class Solution:
    def balancedString(self, s: str) -> int:
        n = len(s)
        cnt, avg = [None] * (n + 1), n//4
        cnt[0] = {'Q':0, 'W':0, 'E':0, 'R':0}
        for i, v in enumerate(s):
            cnt[i+1] = {k:v for k, v in cnt[i].items()}
            cnt[i+1][v] += 1
        
        def check(x):
            for st in range(n - x + 1):
                t = {k:cnt[n][k] - cnt[st+x][k] + cnt[st][k] for k in cnt[0].keys()}
                if all(avg >= t[x] for x in 'QWER'):
                    return True
            return False
            
        l, r = 0, n
        while l < r:
            mid = l + r >> 1
            if check(mid):
                r = mid
            else:
                l = mid + 1   
        return l

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值