08字符串算法练习题解析

字符串算法练习题解析

01验证回文串

问题描述

如果在短语正着读和反着读都一样。则可以认为该短语是一个 回文串

字母和数字都属于字母数字字符。

给你一个字符串 s,如果它是回文串 ,返回 true ;否则,返回 false

  • 1 <= s.length <= 2 * 105
  • s 仅由小写字母和数字组成

输入描述

第一行输入一个字符串表示 s

输出描述

如果它是回文串 ,输出 true ;否则,输出 false

输入样例

amanaplanacanalpanama

输出样例

true

参考代码

#include
#include

using namespace std;

int main(){
	string s;
	cin>>s;

	int l = 0;
	int r = s.size()-1;
	
	while(l

02盛最多水的容器

问题描述

给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0)(i, height[i])

找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。

返回容器可以储存的最大水量。

说明:你不能倾斜容器。

示例:

08字符串算法练习题解析_第1张图片

  • n == height.length
  • 2 <= n <= 10^5
  • 0 <= height[i] <= 10^4

输入描述

第一行输入一个整数表示 n

第二行 n 个由空格分隔的整数

输出描述

输出一个整数,表示容器可以储存的最大水量

输入样例

9

1 8 6 2 5 4 8 3 7

输出样例

49

参考代码

#include
#include

using namespace std;

int main(){
	int n;
	cin>>n;
	vector height(n);
	for(int i=0;i>height[i];
	}

	int l = 0;
	int r = height.size()-1;
	int ans = 0;
	
    while (l < r) {
        int area = min(height[l], height[r]) * (r - l);
        ans = max(ans, area);
        if (height[l] <= height[r]) {
            ++l;
        }
        else {
            --r;
        }
    }
    cout<< ans;
	
	return 0;
} 

03至少有 K 个重复字符的最长子串

问题描述

给你一个字符串 s 和一个整数 k ,请你找出 s 中的最长子串, 要求该子串中的每一字符出现次数都不少于 k 。返回这一子串的长度。

  • 1 <= s.length <= 10^4
  • s 仅由小写英文字母组成
  • 1<=k<=10^5

输入描述

第一行输入一个字符串表示 s

第二行输入一个整数表示k

输出描述

输出满足要求的最长子串的长度

输入样例

aaabb

3

输出样例

3

参考代码

#include
#include
#include

using namespace std;

int main(){
	int k;
	string s;
	cin>>s>>k;
	int ret = 0;
    int n = s.length();
    for (int t = 1; t <= 26; t++) {
        int l = 0, r = 0;
        vector cnt(26, 0);
        int tot = 0;
        int less = 0;
        while (r < n) {
            cnt[s[r] - 'a']++;
            if (cnt[s[r] - 'a'] == 1) {
                tot++;
                less++;
            }
            if (cnt[s[r] - 'a'] == k) {
                less--;
            }

            while (tot > t) {
                cnt[s[l] - 'a']--;
                if (cnt[s[l] - 'a'] == k - 1) {
                    less++;
                }
                if (cnt[s[l] - 'a'] == 0) {
                    tot--;
                    less--;
                }
                l++;
            }
            if (less == 0) {
                ret = max(ret, r - l + 1);
            }
            r++;
        }
    }
    cout<

04尽可能使字符串相等

问题描述

给你两个长度相同的字符串,st

s 中的第 i 个字符变到 t 中的第 i 个字符需要 |s[i] - t[i]| 的开销(开销可能为 0),也就是两个字符的 ASCII 码值的差的绝对值。

用于变更字符串的最大预算是 maxCost。在转化字符串时,总开销应当小于等于该预算,这也意味着字符串的转化可能是不完全的。

如果你可以将 s 的子字符串转化为它在 t 中对应的子字符串,则返回可以转化的最大长度。

如果 s 中没有子字符串可以转化成 t 中对应的子字符串,则返回 0。

  • 1 <= s.length, t.length <= 10^5
  • 0 <= maxCost <= 10^6
  • st 都只含小写英文字母。

输入描述

第一行输入一个字符串表示 s

第二行输入一个字符串表示t

第三行输入一个整数表示maxCost

输出描述

输出可以转化的最大长度

输入样例

abcd

bcdf

3

输出样例

3

参考代码

#include
#include
#include

using namespace std;

int main(){
	int k;
	string s;
	cin>>s>>k;
	int ret = 0;
    int n = s.length();
    for (int t = 1; t <= 26; t++) {
        int l = 0, r = 0;
        vector cnt(26, 0);
        int tot = 0;
        int less = 0;
        while (r < n) {
            cnt[s[r] - 'a']++;
            if (cnt[s[r] - 'a'] == 1) {
                tot++;
                less++;
            }
            if (cnt[s[r] - 'a'] == k) {
                less--;
            }

            while (tot > t) {
                cnt[s[l] - 'a']--;
                if (cnt[s[l] - 'a'] == k - 1) {
                    less++;
                }
                if (cnt[s[l] - 'a'] == 0) {
                    tot--;
                    less--;
                }
                l++;
            }
            if (less == 0) {
                ret = max(ret, r - l + 1);
            }
            r++;
        }
    }
    cout<

05连续的子数组和

问题描述

给你一个整数数组 nums 和一个整数 k ,编写一个函数来判断该数组是否含有同时满足下述条件的连续子数组:

子数组大小 至少为 2 ,且
子数组元素总和为 k 的倍数。
如果存在,返回 true ;否则,返回 false

如果存在一个整数 n ,令整数 x 符合 x = n * k ,则称 xk 的一个倍数。0 始终视为 k 的一个倍数。

  • 1 <= nums.length <= 10^5
  • 0 <= nums[i] <= 10^9
  • 0 <= sum(nums[i]) <= 2^31 - 1
  • 1 <= k <= 2^31 - 1

输入描述

第一行输入一个整数表示 nums.length

第二行输入nums.length个由空格分割的整数表示nums

第三行输入一个整数代表k

输出描述

如果存在,输出 true ;否则,输出 false

输入样例

5

23 2 4 6 7

6

输出样例

true

参考代码

#include
#include
#include

using namespace std;

int main(){
	int n, k;
	cin>>n;
	vector nums(n);
	for(int i=0;i>nums[i];
	}
	cin>>k;

	if (n < 2) {
        cout<<"false";
        return 0;
    }
    unordered_map mp;
    mp[0] = -1;
    int remainder = 0;
    for (int i = 0; i < n; i++) {
        remainder = (remainder + nums[i]) % k;
        if (mp.count(remainder)) {
            int prevIndex = mp[remainder];
            if (i - prevIndex >= 2) {
                cout<<"true";
                return 0;
            }
        } else {
            mp[remainder] = i;
        }
    }
    cout<<"false";
	
	return 0;
} 

06航班预订统计

问题描述

这里有 n 个航班,它们分别从 1n 进行编号。

有一份航班预订表 bookings ,表中第 i 条预订记录 bookings[i] = [firsti, lasti, seatsi] 意味着在从 firstilasti (包含 firstilasti )的 每个航班 上预订了 seatsi 个座位。

请你返回一个长度为 n 的数组 answer,里面的元素是每个航班预定的座位总数。

  • 1 <= n <= 2 * 10^4
  • ``1 <= bookings.length <= 2 * 10^4`
  • bookings[i].length == 3
  • 1 <= first_i <= last_i <= n
  • 1 <= seatsi <= 10^4

输入描述

第一行输入两个整数分别表示 bookings.lengthn

之后bookings.length行,每行3个由空格分割的整数表示[firsti, lasti, seatsi]

输出描述

输出 n 个整数,表示每个航班预定的座位总数。

输入样例

3 5

1 2 10

2 3 20

2 5 25

输出样例

10 55 45 25 25

参考代码

#include
#include
#include

using namespace std;

int main(){
	int m, n;
	cin>>m>>n;
	vector> bookings(m, vector(3));
	for(int i=0;i>bookings[i][0]>>bookings[i][1]>>bookings[i][2];
	}
	
	vector nums(n);
    for (auto& booking : bookings) {
        nums[booking[0] - 1] += booking[2];
        if (booking[1] < n) {
            nums[booking[1]] -= booking[2];
        }
    }
    for (int i = 1; i < n; i++) {
        nums[i] += nums[i - 1];
    }

	for(int i=0;i

你可能感兴趣的:(蓝桥杯,算法,数据结构,蓝桥杯)