前言
最近在刷Leetcode 没搭理牛客网(逃,纪念第一次全AC,在细节上面比较棘手,这方面的基本功我还有待加强,争取做到”心里想什么,代码就能编什么,无Bug“
第一题
给定一个字符串s,你可以从中删除一些字符,使得剩下的串是一个回文串。如何删除才能使得回文串最长呢?
输入描述:
输入数据有多组,每组包含一个字符串s,且保证:1<=s.length<=1000.
输出描述:
对于每组数据,输出一个整数,代表最少需要删除的字符个数。
输入
abcda google
输出
2 2
这道题和Leetcode 583比较像,这道题就是把Leetcode上面的替换成字符串和其逆序字符串之间的最小公共子序列长度问题,我们可以使用同样地方法进行处理,不过需要对结果进行一个额外处理。
- #include <bits/stdc++.h>
- using namespace std;
- int main() {
- string s1;
- while(cin>>s1) {
- string s2(s1.rbegin(), s1.rend());
- int n = s1.length();
- vector<vector<int>> dp(n+1, vector<int>(n+1, 0));
- for(int i = 1; i <= n; ++i) {
- for(int j = 1; j <= n; ++j) {
- if(s1[i-1] != s2[j-1]) {
- dp[i][j] = max(dp[i-1][j], dp[i][j-1]);
- } else {
- dp[i][j] = dp[i-1][j-1] + 1;
- }
- }
- }
- int ans = n - dp[n][n];
- cout<<ans<<endl;
- }
- return 0;
- }
第二题
小Q最近遇到了一个难题:把一个字符串的大写字母放到字符串的后面,各个字符的相对位置不变,且不能申请额外的空间。
你能帮帮小Q吗?
输入描述:
输入数据有多组,每组包含一个字符串s,且保证:1<=s.length<=1000.
输出描述:
对于每组数据,输出移位后的字符串。
输入
AkleBiCeilD
输出
kleieilABCD
这道题的关键在于理清好逻辑,我之前尝试过使用Two pointers进行交换,但是这样却改边了相对位置,后来在草稿纸上推了一下过程,梳理好逻辑。
- #include <bits/stdc++.h>
- using namespace std;
- int main() {
- string s;
- while(cin>>s) {
- int last = 0;
- for(int i = 0; i < s.length(); ++i) {
- if((s[i] >= 'A' && s[i] <= 'Z')) continue; //大写字母跳过,交换小写字母
- for(int j = i; j > last; --j) swap(s[j], s[j-1]); //持续两两交换,直到移动到上一次交换的位置为止
- ++last;
- }
- cout<<s<<endl;
- }
- return 0;
- }
第三题
小Q今天在上厕所时想到了这个问题:有n个数,两两组成二元组,相差最小的有多少对呢?相差最大呢?
输入描述:
输入包含多组测试数据。
对于每组测试数据:
N - 本组测试数据有n个数
a1,a2...an - 需要计算的数据
保证:
1<=N<=100000,0<=ai<=INT_MAX.
输出描述:
对于每组数据,输出两个数,第一个数表示差最小的对数,第二个数表示差最大的对数。
输入
6 45 12 45 32 5 6
输出
1 2
想过暴力求解,时间复杂度是O(N^2),后来发现LTE。那就只能排序再解决问题啦,不过这里面有一个坑,举个例子就是当两个数之间的差值为0时:5 5 5 5,此时的方案数目为C_4^2。这里面需要谨慎处理。
- #include <bits/stdc++.h>
- using namespace std;
- int main() {
- int n;
- while(cin>>n) {
- vector<int> nums;
- while(n--) {
- int tmp; cin>>tmp;
- nums.push_back(tmp);
- }
- n = nums.size();
- sort(nums.begin(), nums.end());
- int minv = INT_MAX, maxv = INT_MIN, mincnt = 1, maxcnt = 1, diff0 = 1;
- //计算最小
- int i = 0;
- while(i < n - 1) {
- int diff = nums[i+1] - nums[i];
- if(diff == 0) {
- minv = 0;
- break;
- }
- if(diff < minv) {
- minv = diff;
- mincnt = 1;
- } else if(diff == minv) {
- ++mincnt;
- }
- ++i;
- }
- if(minv == 0) {
- mincnt = 0;
- while(i < n - 1) {
- int cur = i, cnt = 1;
- while(cur < n - 1) {
- if(nums[cur] == nums[cur+1]) {
- ++cnt;
- ++cur;
- }
- else break;
- }
- mincnt += (cnt * (cnt - 1) / 2);
- i = cur + 1;
- }
- }
- //计算最大
- int l = 1, r = 1;
- for(int i = 0; i < n - 1; ++i) {
- if(nums[i] == nums[i+1]) ++l;
- else break;
- }
- for(int i = n - 1; i > 0; --i) {
- if(nums[i] == nums[i-1]) ++r;
- else break;
- }
- maxcnt = l * r;
- cout<<mincnt<<" "<<maxcnt<<endl;
- }
- }