【C++ 算法进阶】算法提升十一 十二

目录标题

  • 让字符串成为回文串的最少插入次数
    • 题目
    • 题目分析
    • 代码
    • 题目
    • 题目
  • 字符子串 (滑动窗口)
    • 题目
    • 题目分析
    • 代码
  • 最长连续子序列 (头尾表)
    • 题目
    • 题目分析
    • 代码

让字符串成为回文串的最少插入次数

题目

本题为为LC原题 题目如下

在这里插入图片描述

题目分析

这是一道范围尝试模型的动态规划

我们规定dp[i][j]的含义是 让字符串i到j位置成为回文串的最少插入次数

那么假设我们现在要求dp[i][j]的数值我们需要知道什么信息呢?

  1. dp[i + 1][j]

知道了该位置的插入次数之后我们只需要在前面再插入一个字符就能形成回文字符串了

  1. dp[i][j-1]

同理

  1. dp[i+1][j-1]

只有当字符串的i j位置相同的时候我们可以使用这一项 dp[i][j] = dp[i+1][j-1]

代码

class Solution {
public:
    int minInsertions(string s) {
        if (s.size() == 1) {
            return 0;
        }

        vector<vector<int>> dp(s.size() , vector<int>(s.size() , 0));

        int i = 0;
        while (i < s.size() - 1) {
            if (s[i] == s[i+1]) {
                dp[i][i+1] = 0;
            } else {
                dp[i][i+1] = 1;
            }
            i++;
        }

        for (i = s.size() - 3 ; i >=0 ; i--) {
            for (int j = i + 2; j < s.size(); j++) {
                if (s[i] == s[j]) {
                    dp[i][j] = dp[i+1][j-1];
                }else {
                    int p1 = dp[i+1][j] + 1;
                    int p2 = dp[i][j-1] + 1;
                    dp[i][j] = min(p1 , p2);
                }
            }
        }

        return dp[0][s.size() - 1];
    }
};

题目

列举出一种拼接的可能性 (返回一个字符串)

我们在获得dp表之后 只需要从右上角的位置开始依次递推 就能得出最终的答案

题目

列举出所有拼接的可能性 (返回所有可能的字符串)

我们在获得dp表之后 只需要从右上角位置开始依次递推所有的可能性 就能得出最终的答案 (递归)

字符子串 (滑动窗口)

题目

现在给定一个字符串 str 给定一个目标字符串 aim 现在请问 是否在str字符串中有一个连续的子串m和目标字符串(字符的顺序无所谓)

如果有则返回这个连续子串的初始位置 (如果有多个 则返回第一个即可)

如果没有则返回-1

题目分析

本题是一个很明显的滑动窗口问题 (aim的长度是固定的 在字符串str上从左到右移动)

现在的问题是 我们有没有办法优化该窗口查找的时间复杂度

一般的方法是 我们每形成一个滑动窗口 就让该窗口的字符和aim字符串里面的字符进行比较

那么有没有一种更好的方式呢?

带有这种字符数目的题目 我们就要联想到哈希表

我们可以在哈希表中 统计aim每个字符的个数 在第一次形成窗口的时候让这些字符的个数减去窗口中字符的个数 (可以小于0)

之后我们遍历哈希表 查看是否所有的value都为0即可

代码

int process(string& s1, string& aim) {
	unordered_map<char, int> map1;

	for (auto x : aim) {
		map1[x]++;
	}

	int L = 0;
	int R = aim.size() - 1;
	for (int i = L; i <= R; i++) {
		if (map1.count(s1[i]) == 1)
		{
			map1[s1[i]]--;
		}
	}

	for (int i = R + 1; i < s1.size(); i++)
	{
		int r = 0;
		for (auto x : map1) {
			if (x.second != 0) {
				r = 1;
			}
		}
		if (r == 0) {
			return i - aim.size();
		}

		if (map1.count(s1[L]) == 1)
		{
			map1[s1[L]]++;
		}
		L++;
		R++;
		if (map1.count(s1[R]) == 1)
		{
			map1[s1[R]]--;
		}
	}


	int r = 0;
	for (auto x : map1) {
		if (x.second != 0) {
			r = 1;
		}
	}
	if (r == 0) {
		return s1.size() - aim.size();
	}
}

最长连续子序列 (头尾表)

题目

本题为LC原题 题目如下

在这里插入图片描述

题目分析

本题其实和 C++ 算法提升二 中的信息流问题解法一样 还要更简单一点

我们要打印的是一个连续的区间 所以说等数据到了之后让其跟我们现在需要的数据对比的方式肯定不可行

那我们想想看 怎么才能让一段数据连续呢? ---- 单链表

我们可以使用单链表来表示一串连续的数据 但是这里也会出现一个问题

我们怎么保证接收到的数据正好让这一串单链表连接起来呢?

这里提供一种思路

我们创建两章哈希表 头表和尾表

头表 存储一串连续的单链表的头部
尾表 存储一串连续的单链表的尾部

图中的数字代表一个节点

图中的每个数字都代表一个节点 后面其实都有一个指针指向空

假如说现在加入一个四号节点

在这里插入图片描述

那么图片就会变成上面这样
在这里插入图片描述

但是由于3 4 5本身就是一串连续的字节流 所以说头表尾表就会变成下面的形式

在这里插入图片描述

头表中只剩下一个3 尾表中只剩下一个5

假设我们现在想要的第一个数字是2 那么当2来到之后只需要和3 头尾相连 我们打印整个单链表就能得到我们想要的结果了 (当然我们要记得处理下头尾表数据)

代码

struct Node {
    int _num;
    Node* next; // next指针
    Node(int x) {
        _num = x;
        next = nullptr;
    }
};

class Solution {
public:
    int longestConsecutive(vector<int>& nums) {
        unordered_map<int, Node*> head;
        unordered_map<int, Node*> tail;
        unordered_map<int, int> count11;

        for (auto x : nums) {
            if (count11.count(x) == 0) {
                auto* n1 = new Node(x);
                head[x] = n1;
                tail[x] = n1;

                // 查看x是否是某个链表的尾巴
                if (tail.count(x - 1) == 1) {
                    tail[x - 1]->next = n1;
                    head.erase(x);
                    tail.erase(x - 1);
                }

                // 查看x是否是某个链表的头
                if (head.count(x + 1) == 1) {
                    n1->next = head[x + 1];
                    tail.erase(x);
                    head.erase(x + 1);
                }

                count11[x] = 1;
            }
        }

        int ans = 0;
        for (auto& x : head) {
            auto cur = x.second;
            int count = 0;
            while (cur) {
                cur = cur->next;
                count++;
            }
            ans = max(ans, count);
        }

        return ans;
    }
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/913494.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux(CentOS)安装 MySQL

CentOS版本&#xff1a;CentOS 7 三种安装方式&#xff1a; 一、通过 yum 安装&#xff0c;最简单&#xff0c;一键安装&#xff0c;全程无忧。 二、通过 rpm 包安装&#xff0c;需具备基础概念及常规操作。 三、通过 gz 包安装&#xff0c;需具备配置相关操作。 --------…

6.1 软件测试:软件质量与测试

软件质量与测试 1、软价质量保证1.1 软件质量质量控制QC&#xff1a;QUALITY CONTROL质量保证QA:QUALITY ASSURANCE质量成本软件质量软件质量保证 1.2 软件评审1.3 软件可靠性 2、软件测试2.1 软件测试过程模型软件测试策略软件测试策略V模型回归测试软件测试策略原则软件测试策…

JavaEE进阶---SpringMVC(二)请求里面十种参数类型

文章目录 1.请求1.1接受单个参数的请求1.2多个参数的传递1.3传递对象1.4参数重命名1.5设置参数是非必传的1.6数组的请求方式1.7如何传递集合1.8传递json数据1.9获取url里面的参数1.10获取文件 1.请求 1.1接受单个参数的请求 下面的这个就是我们的项目代码&#xff0c;都是单个…

FIPS203 后量子安全ML-KEM(标准简读)

FIPS 203是美国国家标准与技术研究院&#xff08;NIST&#xff09;发布的关于模块格基密钥封装机制&#xff08;ML-KEM&#xff09;的标准&#xff0c;旨在提供一种能抵御量子计算机攻击的密钥建立方案。以下是对该文档的详细总结&#xff1a; 标准概述 目的与范围&#xff…

Android GPU纹理数据拷贝

在 Android 开发中读取纹理数据有以下几种方法&#xff1a; glReadPixelsImageReaderPBO&#xff08;Pixel BufferObject&#xff09; HardwareBuffer 1. glReadPixels glReadPixels 是 OpenGL ES 的 API&#xff0c;通常用于从帧缓冲区中读取像素数据&#xff0c;OpenGL ES…

NVM切换本地node版本

1、下载nvm https://github.com/coreybutler/nvm-windows/releases nvm-windows 然后点击nvm-setup.exe下载&#xff0c;尽可能都选择默认安装选项 2、nvm常用命令 使用以下命令安装特定版本的 Node.js&#xff1a; nvm install <version> nvm install 14.17.0 使…

GNN系统学习:消息传递图神经网络

引言 在开篇中我们介绍了&#xff0c;为节点生成节点表征&#xff08;Node Representation&#xff09;是图计算任务成功的关键&#xff0c;我们要利用神经网络来学习节点表征。 消息传递范式是一种聚合邻接节点信息来更新中心节点信息的范式&#xff0c;它将卷积算子推广到了…

C语言 | Leetcode C语言题解之第554题砖墙

题目&#xff1a; 题解&#xff1a; struct HashTable {int key, val;UT_hash_handle hh; };int leastBricks(int** wall, int wallSize, int* wallColSize) {struct HashTable* cnt NULL;for (int i 0; i < wallSize; i) {int n wallColSize[i];int sum 0;for (int j …

全文检索ElasticSearch到底是什么?

学习ElasticSearch之前&#xff0c;我们先来了解一下搜索 1 搜索是什么 ① 概念&#xff1a;用户输入想要的关键词&#xff0c;返回含有该关键词的所有信息。 ② 场景&#xff1a; ​ 1互联网搜索&#xff1a;谷歌、百度、各种新闻首页&#xff1b; ​ 2 站内搜索&#xff…

【C++】vector模拟实现、迭代器失效问题(超详解)

vector会使用之后我们来模拟实现一下&#xff0c;通过对vector的模拟实现&#xff0c;我们来说一下迭代器失效问题。 1.准备工作 在头文件vector.h里声明和实现函数&#xff0c;然后在test.cpp里测试代码的正确性。 在vector.h中用命名空间分隔一下&#xff0c;因为c库里面也有…

前端CSS3 渐变详解

文章目录 CSS3 渐变详解一、引言二、CSS3 渐变基础1、线性渐变1.1、基本线性渐变1.2、改变渐变方向 2、径向渐变2.1、基本径向渐变2.2、设置径向渐变的中心 三、高级渐变技巧1、重复渐变1.1、重复线性渐变1.2、重复径向渐变 四、总结 CSS3 渐变详解 一、引言 在现代网页设计中…

Docker学习—Docker的安装与使用

Docker安装 1.卸载旧版 首先如果系统中已经存在旧的Docker&#xff0c;则先卸载&#xff1a; yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-engine2.配置Docker的yum库 首先…

M1M2 MAC安装windows11 虚拟机的全过程

M1/M2 MAC安装windows11 虚拟机的全过程 这两天折腾了一下windows11 arm架构的虚拟机&#xff0c;将途中遇到的坑总结一下。 1、虚拟机软件&#xff1a;vmware fusion 13.6 或者 parallel 19 &#xff1f; 结论是&#xff1a;用parellel 19。 这两个软件都安装过&#xff0…

蓝桥杯备考——算法

一、排序 冒泡排序、选择排序、插入排序、 快速排序、归并排序、桶排序 二、枚举 三、二分查找与二分答案 四、搜索&#xff08;DFS&#xff09; DFS&#xff08;DFS基础、回溯、剪枝、记忆化&#xff09; 1.DFS算法&#xff08;深度优先搜索算法&#xff09; 深度优先搜…

‘conda‘ 不是内部或外部命令,也不是可运行的程序或批处理文件,Miniconda

下载了conda&#xff0c;但是在cmd里执行conda --version会显示’conda’ 不是内部或外部命令&#xff0c;也不是可运行的程序或批处理文件。 原因是环境变量里没有添加conda&#xff0c;无法识别路径。 需要在系统环境变量里添加如下路径&#xff1a; 保存之后重新打开cmd&am…

UE5 随机生成地牢关卡

参考视频&#xff1a;【UE5 | 教程 | 地编】虚幻引擎5 中创建史诗级 程序化 地下城_哔哩哔哩_bilibili 首先创建一个父项Actor 这个BOX碰撞提是和地板重叠的 这三个是场景组件&#xff0c;这个ExitsFolder下面的箭头等会会在子蓝图中添加 接下来创建BP_MasterRoom的子蓝图&…

Qt信号和槽-->day04

Qt信号和槽 标准的信号和槽函数Qt中的槽函数Qt中的信号 connect案例 自定义信号和槽案例分析 信号槽的拓展信号连接信号案例 信号槽的两种连接方式Qt5中的处理方式Qt4中的处理方式Qt5处理信号槽重载问题案例 lambda表达式简单案例Qt中的应用 补充知识点 标准的信号和槽函数 QW…

十大经典排序算法-冒泡算法详解介绍

1、十大经典排序算法 排序算法是《数据结构与算法》中最基本的算法之一。 排序算法可以分为内部排序和外部排序&#xff0c;内部排序是数据记录在内存中进行排序&#xff0c;而外部排序是因排序的数据很大&#xff0c;一次不能容纳全部的排序记录&#xff0c;在排序过程中需要…

ASMR助眠声音视频素材去哪找 吃播助眠素材网站分享

在快节奏的现代生活中&#xff0c;越来越多的人感到压力山大&#xff0c;许多人开始寻求助眠和放松的方式。而ASMR&#xff08;自发性知觉经络反应&#xff09;助眠声音视频&#xff0c;凭借其独特的声音刺激和放松效果&#xff0c;成为了睡前的“神器”。如果你是一位内容创作…

【Linux】常用命令(2.6万字汇总)

文章目录 Linux常用命令汇总1. 基础知识1.1. Linux系统命令行的含义1.2. 命令的组成 2. 基础知识2.1. 关闭系统2.2. 关闭重启2.3. 帮助命令&#xff08;help&#xff09;2.4. 命令说明书&#xff08;man&#xff09;2.5. 切换用户&#xff08;su&#xff09;2.6.历史指令 3.目录…