笔试专题(十)

文章目录

对称之美(双指针)

题目链接

题解

  1. 双指针
  2. 用left标记左边的字符串,用right标记右边的字符,如果左边的字符串和右边的字符串出现相同的字符,left++,right--,直到两个字符串相遇或者是分离
  3. 可以用二维的哈希表进行判断字符串中是否有相同的字符,x标记在第几个字符串,y标记26个字符,如果在左边和右边都出现标记为true
  4. 细节处理:有多组测试用例,需要每次对vis进行数据清空,防止干扰下次的判断

代码

cpp 复制代码
#include<iostream>
#include<string>
#include<cstring>
using namespace std;

int n,t;
bool vis[110][26];// 有100个字符串,每个字符串中有26个字符

bool check(int left,int right)
{
    for(int i = 0;i < 26;i++)
    {
        if(vis[left][i] && vis[right][i]) return true;
    }
    return false;
}
int main()
{
    cin >> t;
    
    while(t--)
    {
        memset(vis,0,sizeof(vis));
        cin >> n;
        string s;
        for(int i = 0;i < n;i++)
        {
            cin >> s;
            for(auto ch : s)
            {
                vis[i][ch - 'a'] = true;
            }
        }
        
        int left = 0,right = n - 1;
        while(left < right)
        {
            if(!check(left,right)) break;
            else 
            {
                left++;
                right--;
            }
        }
        if(right > left) cout << "No" << '\n';
        else cout << "Yes" << '\n';
    }
    
    return 0;
} 

连续子数组最大和(线性dp)

题目链接

题解

  1. 以i位置为结尾的子数组的最大的和,可以是i位置本身,也可以是前面的最大和加上i位置的数
  2. 细节处理:dp[0]映射为0,返回dp表里面子数组的最大和,如果dp[i-1] + arr[i] 和 arr[i] 表示dp[i] 中的最大值,如果dp[i-1] 小于0的话,那么最大值是arr[i],如果dp[i-1]大于0的话,那么最大值是dp[i-1] + arr[i]
  3. 必须是连续的子数组,连续:可以从0位置或者中间其他位置开始向后

代码

cpp 复制代码
#include <iostream>
using namespace std;


const int N = 2e5 + 10;
int a[N];
int dp[N];

int main()
{
    int n;
    cin >> n;
    
    for(int i = 0;i < n;i++) cin >> a[i];

    int ans = -110;
    for(int i = 1;i <= n;i++)
    {
        // a[i-1] 保证映射关系的正确性
        dp[i] = max(dp[i-1],0) + a[i-1];
        // 子数组中的最大和
        ans = max(dp[i],ans);
    }
    cout << ans << '\n';

    return 0;
} 

最长回文子序列(区间dp)

题目链接

题解

  1. 细节处理:初始化要[i+1][j],[i+1][j-1],[i,j-1]这三个点,i > j 的点都初始化为0,i = j的点都初始化为1
  2. 填表顺序:从下往上,从左往右填,每次都要用到下面的和左边的数

代码

cpp 复制代码
#include <iostream>
#include<string>
#include<vector>
using namespace std;

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

    int n = s.size();
    vector<vector<int>> dp(n,vector<int>(n));
    dp[0][0] = 1,dp[n-1][n-1] = 1;

    for(int i = n-2;i >= 0;i--)
    {
        for(int j = i;j < n;j++)
        {
            if(i == j) dp[i][j] = 1;
            else if(i > j) dp[i][j] = 0;
            else if(i < j)
            {
                if(s[i] == s[j]) dp[i][j] = dp[i+1][j-1] + 2;
                else dp[i][j] = max(dp[i+1][j],dp[i][j-1]);
            }  
        }
    }
    
    cout << dp[0][n-1] << '\n'; 

    return 0;
}
相关推荐
咚咚轩10 天前
蓝桥杯3503 更小的数
双指针
奔跑的废柴14 天前
LeetCode 925. 长按键入 java题解
java·算法·leetcode·双指针
阳洞洞21 天前
leetcode 18. 四数之和
leetcode·双指针
阳洞洞23 天前
leetcode 15. 三数之和
leetcode·双指针
阳洞洞1 个月前
leetcode 141. Linked List Cycle
数据结构·leetcode·链表·双指针
阳洞洞1 个月前
leetcode 142. Linked List Cycle II
数据结构·leetcode·链表·双指针
卷卷的小趴菜学编程1 个月前
算法篇-----滑动窗口
数据结构·算法·双指针·滑动窗口·哈希表·数组相关
懒懒小徐1 个月前
华为OD机试真题 Java 实现【水库蓄水问题】
java·算法·华为od·双指针
阳洞洞1 个月前
滑动窗口leetcode 209和76
算法·leetcode·双指针·滑动窗口
阳洞洞1 个月前
leetcode 977. Squares of a Sorted Array
算法·leetcode·双指针