【动态规划算法】-子序列问题题型(27-34题)

news2024/9/20 8:08:06

在这里插入图片描述
💖作者:小树苗渴望变成参天大树🎈
🎉作者宣言:认真写好每一篇博客💤
🎊作者gitee:gitee✨
💞作者专栏:C语言,数据结构初阶,Linux,C++ 动态规划算法🎄
如 果 你 喜 欢 作 者 的 文 章 ,就 给 作 者 点 点 关 注 吧!

文章目录

  • 前言
  • 第二十七题:[300. 最长递增子序列](https://leetcode.cn/problems/longest-increasing-subsequence/)
  • 第二十八题:[376. 摆动序列](https://leetcode.cn/problems/wiggle-subsequence/)
  • 第二十九题:[673. 最长递增子序列的个数](https://leetcode.cn/problems/number-of-longest-increasing-subsequence/)
  • 第三十题:[646. 最长数对链](https://leetcode.cn/problems/maximum-length-of-pair-chain/)
  • 第三十一题:[1218. 最长定差子序列](https://leetcode.cn/problems/longest-arithmetic-subsequence-of-given-difference/)
  • 第三十二题:[873. 最长的斐波那契子序列的长度](https://leetcode.cn/problems/length-of-longest-fibonacci-subsequence/)
  • 第三十三题:[1027. 最长等差数列](https://leetcode.cn/problems/longest-arithmetic-subsequence/)
  • 第三十四题:[446. 等差数列划分 II - 子序列](https://leetcode.cn/problems/arithmetic-slices-ii-subsequence/)


前言

今天我们开始讲解关于子序列数组的动态规划算法相关的题型,这个题型和子数组题型的分析有点相似,都是以什么位置为结尾然后分开讨论,但是每题的条件又是不同的,所以也是有分析难度的,博主媒体会详细的给大家介绍,大家不用担心。


第二十七题:300. 最长递增子序列

这题是我们子序列的最经典题型,后面讲的题目都是按照这题的思路来解题,所以这题是非常关键的,我会详细的给大家讲解一下。

在这里插入图片描述

动态规划算法:

1. 状态表示:经验+题目要求

dp[i]表示:以i位置为结尾的所有子序列中,最长子序列的长度

2. 状态转移方程:
在这里插入图片描述
if(nums[i]>nums[j])

    dp[i]=dp[j]+1;

3. 初始化:保证数组不越界
我们发现不管怎么样自身都是一个子序列,所以长度最少都为1,所以我们dp表的第一种单独作为一个子序列的情况就不用考虑了,所以我们一开始就都初始化为1
4. 填表顺序:
从左往右
5. 返回值:
通过状态表示来看,我们以任意位置都有可能是最长子序列数组,所以应该返回dp表中的最大值

代码实现:

class Solution {
public:
    int lengthOfLIS(vector<int>& nums) {
        int n=nums.size();
        //1.创建dp表+初始化
        vector<int> dp(n,1);
        int ret=1;
        //填表
        for(int i=1;i<n;i++)
        {
            for(int j=0;j<i;j++)
            {
                if(nums[j]<nums[i])
                {
                    dp[i]=max(dp[j]+1,dp[i]);
                }
            }
            ret=max(ret,dp[i]);
        }
        //返回值
        return ret;
    }
};

运行结果:
在这里插入图片描述

第二十八题:376. 摆动序列

题目解析:
在这里插入图片描述

动态规划算法:
1. 状态表示:经验+题目要求
这题和子数组系列中的乘积为最大正数的最长数组那题非常像,因为他要考虑前面的子数组到底最后的乘积是多少,可能为正也可能为负,所以我们需要定义两个状态表示,这题也是一样的,前面的摆动子序列最后一个是“上升”,还是“下降”状态,这样就没办法知道最后一个元素和前面是上升状态对,还是下降状态对,所以我们也定义两个状态表示:

f[i]表示:以i位置为结尾,所有子序列数组中,最后是“上升”趋势的最长子序列的长度

g[i]表示:以i位置为结尾,所有子序列数组中,最后是“下降”趋势的最长子序列的长度

2. 状态转移方程:
我们的分析还是和上题的分析是一样的,子序列的问题因为不是连续的,最后一个和前面一个位置不是连续的,前面的任何位置都有可能,所以此时需要一个变量j来控制前面的一部分的结尾部分,所有子序列问题一半都比子数组问题多一个循环条件,我们来看这题的状态转移方程的分析:
在这里插入图片描述
if(nums[j]<nums[i])

                f[i]=max(f[i],g[j]+1);

if(nums[j]>nums[i])

                g[i]=max(g[i],f[j]+1);

3. 初始化:保证数组不越界
和上题一样,我们不管以什么位置为结尾,序列长度最少都为1,所哟我们都初始化为1就可以了,那我们两个状态转移方程的的第一种情况都不用考虑了。

两个表都初始化为1

4. 填表顺序:
从左往右,两个表一起填写
5. 返回值:
因为不知道那个位置结尾的摆动序列最长,也不知道最后是什么趋势,最后返回值是两边当中的最大值

return max(Max,max(f[i],g[i]));

代码实现:

class Solution {
public:
    int wiggleMaxLength(vector<int>& nums) {
        int n=nums.size();
        //创建dp表和初始化
        vector<int> f(n,1);
        auto g=f;
        int Max=1;
        //填表
        for(int i=1;i<n;i++)
        {
            for(int j=0;j<=i;j++)
            {
                if(nums[i]>nums[j])
                {
                    f[i]=max(f[i],g[j]+1);
                }
                if(nums[i]<nums[j])
                {
                    g[i]=max(g[i],f[j]+1);
                }

            }
            Max=max(Max,max(f[i],g[i]));//一边填表一边找出最大值
        }
        //返回值
        return Max;
    }
};

运行结果:
在这里插入图片描述

第二十九题:673. 最长递增子序列的个数

题目解析:
在这里插入图片描述
先讲解一个小算法:求最大值出现的次数(只能比遍历一次数组)
在这里插入图片描述
来看代码:

int main()
{
	int nums[] = { 2,2,3,1,3,2,1,0 };
	int maxval = nums[0];
	int count = 1;
	for (int i = 0; i < 8; i++)
	{
		if (nums[i] == maxval)count++;
		else if (nums[i] > maxval)maxval = nums[i], count=1;
	}
	cout << maxval << " " << count << endl;
	return 0;
}

在这里插入图片描述

知道这个算法以后我们再来做这个题目就简单了。

动态规划算法:

1. 状态表示:经验+题目要求
通过题目要求我们要定义两个状态表示:

len[i]表示:以i位置为结尾,所有递增子序列中的最长子序列的长度
count[i]表示:以i位置为结尾,所有递增子序列中的最长子序列的个数

2. 状态转移方程:
我们的len[i]应该为
if(nums[i]>nums[j])

    len[i]=max(len[j]+1,len[i]);

为了和count[i]一起,我们修改成下面的场景

if(nums[j] < nums[i]) 这个前提下才能构成递增子序列

            if(len[j] + 1 == len[i])
                count[i] += count[j];
            else if(len[j] + 1 > len[i]) // 重新计数
                len[i] = len[j] + 1, count[i] = count[j];

3. 初始化:保证数组不越界
不管怎样自身都可以构成递增子序列,所以两个表都初始化为1
4. 填表顺序:
从左往右,两表同时填
5. 返回值:
因为不知道那个位置的子序列最长,所以也要找出最长长度,看出现的次数
还是按照之前那的小算法

代码实现:

class Solution {
public:
    int findNumberOfLIS(vector<int>& nums) {
    int n = nums.size();
    vector<int> len(n, 1), count(n, 1); // 1. 创建 dp 表 + 初始化
    int retlen = 1, retcount = 1; // 记录最终结果
    for(int i = 1; i < n; i++) // 2. 填表
    {
        for(int j = 0; j < i; j++)
        {
            if(nums[j] < nums[i])
            {
                if(len[j] + 1 == len[i])
                    count[i] += count[j];
                else if(len[j] + 1 > len[i]) // 重新计数
                    len[i] = len[j] + 1, count[i] = count[j];
            }
        }
        if(retlen == len[i])
            retcount += count[i];
        else if(retlen < len[i]) // 重新计数
            retlen = len[i], retcount = count[i];
    }
    // 3. 返回结果
    return retcount;
    }   
};

运行结果:
在这里插入图片描述

第三十题:646. 最长数对链

题目解析:
在这里插入图片描述

预处理:排序
在这里插入图片描述

动态规划算法:
1. 状态表示:经验+题目要求

dp[i]表示:以第i行位置为结尾的最长数对链的长度

2. 状态转移方程:
分析方法时前面时一样的,把一个数对堪称一个整体
在这里插入图片描述

if(nums[i][0]>nums[j][1])

                dp[i]=dp[j]+1;

3. 初始化:保证数组不越界
按照最坏的情况去初始化,最少的数对链长度都为1,所以全部初始化为1
4. 填表顺序:
从左往右
5. 返回值:
不知道以哪个位置结尾的数对链最长,所以是返回dp表里面的最大值,这个可以一边填表一个找出来最大值
代码实现:

class Solution {
public:
    int findLongestChain(vector<vector<int>>& nums) {

        sort(nums.begin(),nums.end());
        int n=nums.size();
        vector<int> dp(n,1);
        int ret=1;
        for(int i=1;i<n;i++)
        {
            for(int j=0;j<i;j++)
            {
                if(nums[i][0]>nums[j][1])
                {
                    dp[i]=max(dp[j]+1,dp[i]);
                }
            }
            ret=max(ret,dp[i]);
        }
        return ret;
    }
};

运行结果:
在这里插入图片描述

第三十一题:1218. 最长定差子序列

题目解析:
在这里插入图片描述

动态规划算法:

1. 状态表示:经验+题目要求

dp[i]表示:以i位置的元素为结尾构成的定差子序列中最长定差子序列的长度

2. 状态转移方程:
在这里插入图片描述

hash[arr[i]]=hash[arr[i]-difference]+1;

3. 初始化:保证数组不越界
这题是通过元素当成下标,也没有负数,所以不需要初始化hash的第一个元素
4. 填表顺序:
从左往右
5. 返回值:
返回hash表里面的最大值

代码实现:

class Solution {
public:
    int longestSubsequence(vector<int>& arr, int difference) {
       unordered_map<int,int> hash;//第一个int是下标,表示第i个元素
       int ret=1;
       for(int i=0;i<arr.size();i++)
       {
           hash[arr[i]]=hash[arr[i]-difference]+1;
           //dp[i]=dp[j]+1;判断条件为arr[i]-difference

           ret=max(hash[arr[i]],ret);
       }
     return ret;
    }
};

运行结果:
在这里插入图片描述

第三十二题:873. 最长的斐波那契子序列的长度

题目解析:
在这里插入图片描述

动态规划算法:

1. 状态表示:经验+题目要求
在这里插入图片描述

dp[i][j]表示:以i位置以及j位置的元素为结尾的斐波那契子序列种最长的斐波那契子序列的长度,i位置在j位置前面,这样就保证i不等于j,方便初始化

2. 状态转移方程:
在这里插入图片描述

3. 初始化:保证数组不越界

因为我们dp[i][j]里面存放的是长度而且不会只有一个元素的情况,所以把dp[i][j]都初始化为2,只会使用到i<j位置的值,其余的值初始化什么都无所谓,使用不到的,所以索性都初始化为2.

4. 填表顺序:
从上往下
我们的j是最后一个位置,所以从第2个位置开始算才有意义
我们的i是最后一个位置的前一个位置,所以从第1个位置开始算才有意义

5. 返回值:
我们不知道以那两个位置为结尾时候的长度最长,所以返回dp表里面的最大值,但是我们的最短长度都应该是3,如果找到就返回0,此时dp表里面的值最小都为2,所以要判断一下ret<3?0:ret

代码实现:

class Solution {
public:
    int lenLongestFibSubseq(vector<int>& arr) {
        int n=arr.size();
        unordered_map<int,int> hash;
        for(int i=0;i<n;i++)
        {
            hash[arr[i]]=i;//将arr中的下标和元素绑定
        }

        //创建一个二维dp表,并初始化为2
        vector<vector<int>> dp(n,vector<int>(n,2));

        //填表,注意i,j起始位置
        int ret=2;
        for(int j=2;j<n;j++)
        {
            for(int i=1;i<j;i++)
            {
                int a=arr[j]-arr[i];
                if(a<arr[i]&&hash.count(a))
                {
                    dp[i][j]=dp[hash[a]][i]+1;
                    //dp[i][j]=dp[k][i]+1;
                }
                ret=max(ret,dp[i][j]);//确定一个dp[i][j]就判断是不是最大值
            }
        }
        return ret<3?0:ret;
    }
};

运行结果:
在这里插入图片描述

第三十三题:1027. 最长等差数列

题目解析:
在这里插入图片描述

动态规划算法:

1. 状态表示:经验+题目要求
这个和上面的题目有点类似,以i位置为结尾的元素的能否和前面构成等差数列,是需要前面两个位置的值,不像子数组问题,是连续的,前面两个元素的位置就是i-1和I-2位置的值,但是子序列问题不是的,所以不行,斐波那契和等差数列都是需要前面两个位置的值才能办证后面的值能否推出来,也就是有了后两个元素的值,就能推出来倒数第三个元素的值,所以此题的状态表示为:

dp[i][j]表示:以i位置的元素及j位置的元素为结尾的所有子序列中,最长等差子序列的长度

2. 状态转移方程:
在这里插入图片描述

3. 初始化:保证数组不越界
初始化使得将dp表里面的值都初始化为2,hash的第一个位置初始化0;
4. 填表顺序:
有两种:
在这里插入图片描述

5. 返回值:
返回值dp表中的最大值

代码实现:

class Solution {
public:
    int longestArithSeqLength(vector<int>& nums) {
        int n=nums.size();
        unordered_map<int,int> hash;
        hash[nums[0]]=0;

        vector<vector<int>> dp(n,vector<int>(n,2));

        int ret=2;
        for(int i=1;i<n;i++)
        {
            for(int j=i+1;j<n;j++)
            {
                int a=2*nums[i]-nums[j];
                if(hash.count(a))
                {
                    dp[i][j]=dp[hash[a]][i]+1;
                }
                ret=max(ret,dp[i][j]);
            }
            hash[nums[i]]=i;
        }
        return ret;
    }
};

运行结果:

在这里插入图片描述

第三十四题:446. 等差数列划分 II - 子序列

题目解析:
在这里插入图片描述

动态规划算法:

1. 状态表示:经验+题目要求
这个题目第29题还有33题很像,将他们的思想结合起来了,我们的等差数列,将状态表示定位dp[i]是不行的,原因是你要求的dp[i]肯定是需要使用到dp[i-1],dp[i-2]等位置的值,显然没有办法知道公差是多少,最少需要三个数,所以我们要将状态表示定义为dp[i][j]表示最后两个位置的值,往前面推导

dp[i][j]表示:以i位置以及j位置为结尾的所有等差数列的个数(i<j)

2. 状态转移方程:
这种状态转移方程为了少一个循环,通常会将值放在hash表里面,直接通过元素定位到对应的下标,元素过多就把hash表里面的值定义成一个数组类型,是存放原数组下标的数组,顶多遍历这个下标数组就可以了。
在这里插入图片描述

3. 初始化:保证数组不越界

我们单独的两个元素不构成等差数列,所以将dp表全部初始化为0

4. 填表顺序:

我们先固定倒数第一个数j,从下标为2的地方开始遍历才有意义
在枚举倒数第二个数i,从下标为1的地方开始遍历才有意义

5. 返回值:
返回dp表里面所有值的和

代码实现:

class Solution {
public:
    int numberOfArithmeticSlices(vector<int>& nums) {
        int n=nums.size();
        unordered_map<long long,vector<int>> hash;
        for(int i=0;i<n;i++)//将原数组元素和下标数组绑定
        {
            hash[nums[i]].push_back(i);
        }
        int sum=0;
        vector<vector<int>> dp(n,vector<int>(n));//创建dp表
        for(int j=2;j<n;j++)
        {
            for(int i=1;i<j;i++)
            {
                long long a=(long long)2*nums[i]-nums[j];//防止溢出
                if(hash.count(a))//判断a存不存在
                {
                    for(auto k:hash[a])//遍历下标数组,为a的元素不止一个
                    {
                        if(k<i)
                        {
                            dp[i][j]+=dp[k][i]+1;
                        }
                    }
                }
                sum+=dp[i][j];//求和
            }
        }
        //返回值
        return sum;
    }
};

运行结果:
在这里插入图片描述

至此我们的子序列问题就讲解到这里了,大家应该发现号几次都是和hash表有关的题目,可以帮助我们很快定位到元素,因为i位置前面的元素不确定,但又不想直接遍历去找可以使用hash的方式,下一个题型是回文串问题,我们一起来期待吧
请添加图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

svn还原本地代码

svn代码还原 问题描述&#xff1a;在vscode中修改了代码&#xff0c;没有提交&#xff0c;而且不小心点击了svn更新&#xff0c;导致本地修改的最新代码被覆盖&#xff0c;因为没有提交&#xff0c;所以远程仓库中也没有刚才修改的代码记录 解决&#xff1a; 通过vscode的时间…

远距离传输大型文件:如何应对不同地区的网络环境和带宽约束

在现代社会中&#xff0c;远程传输大文件已经变得非常常见了。无论是个人生活还是各种组织之间的合作和协作&#xff0c;都需要频繁地进行文件传输。但是&#xff0c;由于不同地区的网络状况和带宽限制&#xff0c;传输大文件可能会遇到很多问题。因此&#xff0c;如何应对不同…

PSP - 蛋白质序列搜索算法 MMseqs2 与 HHblits 的搜索结果差异

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/132025401 在 AlphaFold2 中&#xff0c;使用 HHblits 算法搜索 BFD 与 UniRef30&#xff0c;输出 bfd_uniref_hits.a3m 文件。MMseqs2 优化搜索速…

Selenium-用这个框架自动化任何你想做的事情!

Chrome DevTools 简介 Chrome DevTools 是一组直接内置在基于 Chromium 的浏览器&#xff08;如 Chrome、Opera 和 Microsoft Edge&#xff09;中的工具&#xff0c;用于帮助开发人员调试和研究网站。 借助 Chrome DevTools&#xff0c;开发人员可以更深入地访问网站&#xf…

职责链模式-请求的链式处理

在实际开发中&#xff0c;对于一个请求我们要经过层层过滤&#xff1a;身份验证 -> 权限验证 -> 实际业务处理。请求沿着一个链在传递&#xff0c;每一层都可以处理该请求。而“职责链模式”就是专门用于处理这种请求链式传递的模式。 1 职责链模式概述 避免将请求发送…

Kubernetes系列

文章目录 1 详解docker,踏入容器大门1.1 引言1.2 初始docker1.3 docker安装1.4 docker 卸载1.5 docker 核心概念和底层原理1.5.1 核心概念1.5.2 docker底层原理 1.6 细说docker镜像1.6.1 镜像的常用命令 1.7 docker 容器1.8 docker 容器数据卷1.8.1 直接命令添加1.8.2 Dockerfi…

2023-07-31 C语言根据错误号打印详细的错误信息perror(““) 或者strerror(errno)

一、C 语言可以使用perror("perror output"); 或 strerror(errno)打印详细的错误信息。 二、需要的头文件#include <errno.h>。 三、实例测试&#xff0c;这里我让open一个linux 底层杂项设备失败的情况&#xff0c;返回的是一个负数&#xff0c;强制返回-EN…

【shell】获取ping的时延数据并分析网络情况

网络情况经常让我们头疼&#xff0c;每次都需要手动在终端ping太麻烦了&#xff0c;不如写个脚本ping并将数据带上时间戳存入文件&#xff0c;然后也可以分析哪个时间段网络比较差。 创建一个demo.sh文件&#xff1a; #!/bin/bash # 清理日志 net_path"./network/"…

性能测试必备监控技能windows篇

前言 在手头没有专门的第三方监控时&#xff0c;该怎么监控服务指标呢&#xff1f;本篇就windows下监控进行分享&#xff0c;也是我们在进行性能测试时&#xff0c;必须掌握的。下面我们就windows下常用的三种监视工具进行说明&#xff1a; 任务管理器 资源监视器 性能监视器…

AD21 PCB设计的高级应用(一)BGA的扇出方式

&#xff08;一&#xff09;BGA的扇出方式 1.软件自动扇出方式2.手工扇出方式3.多种规格BGA的出现方式 1.软件自动扇出方式 在进行PCB设计时,常会遇到 BGA类型的封装&#xff0c;此类封装需要扇出用于后期的布线。BGA 扇出与否的比对如图所示。 (1)在进行利用软件自动扇出 BGA…

移动端适配布局rem和vw

在日益发展的移动互联网时代&#xff0c;作为前端开发者&#xff0c;我们必须了解和掌握各种移动端显示效果的适配技术。在众多适配方案中&#xff0c;使用rem和vw进行布局是当前最为流行和普遍使用的两种技术。通过合理运用这两种技术&#xff0c;我们可以让我们的网页在不同尺…

HCIP——前期综合实验

前期综合实验 一、实验拓扑二、实验要求三、实验思路四、实验步骤1、配置接口IP地址2、交换机配置划分vlan10以及vlan203、总部分部&#xff0c;骨干网配置OSPF分部总部骨干网 4、配置BGP建立邻居关系总部骨干网分部 5、发布用户网段6、将下一跳改为本地7、允许AS重复8、重发布…

揭秘!头条百科词条创建全过程及技巧解析

随着互联网时代的到来&#xff0c;人们获取信息的方式越来越便捷。作为国内领先的信息平台&#xff0c;头条百科成为了很多人查阅知识的首选。然而&#xff0c;如何在头条上创建百科词条&#xff0c;让更多人了解和熟知自己呢&#xff1f;本文伯乐网络传媒将为您揭开这个谜团&a…

何恺明把神经网络做深了,谷歌把神经网络的入口拉大了,又深又大,才成为今天的大模型

openai chatgpt 相关_个人渣记录仅为自己搜索用的博客-CSDN博客 大神回归学界&#xff1a;何恺明宣布加入 MIT 如今大模型都在使用的 transformer 的编码器和解码器&#xff0c;里面都有源自 ResNet 的残差链接。 「在 ResNet 之后就可以有效地训练超过百层的深度神经网络&…

Windows 实例如何开放端口

矩池云 Windows 实例相比于 Linux 实例&#xff0c;除了在租用机器的时候自定义端口外&#xff0c;还需要在 Windows防火墙中添加入口规则。接下来将教大家如何设置 Windows 防火墙&#xff0c;启用端口。 租用成功后通过 RDP 链接连接服务器&#xff0c;然后搜索防火墙&#x…

uniapp使用getStorage对属性赋值无效

1正常set(get)storage都是可以正常使用的 2.但对属性进行赋值的时候&#xff0c;却发现this.name并没有发生变化 3. 在里面打印this发现&#xff0c;在set*getStorage中并不能拿到this. 4.优化代码 这样就可以给this.name成功赋值

pinia 状态管理器详细文档记录,如何使用pinia看着一篇就够了!!!

目录 安装Pinia 定义store 1.option对象写法&#xff1a; 2.Setup 函数写法 使用store 接下来细化一下pinia的三大核心概念 state、action、getter 一、state 访问 state 重置 state 变更 state 替换 state 订阅 state 二、Getter 访问其他 getter 向 getter 传递…

116、你是如何理解Spring事务的传播机制的?底层是如何实现的?

你是如何理解Spring事务的传播机制的&#xff1f;底层是如何实现的&#xff1f; 一个线程在运行过程中&#xff0c;可能会连续调用好几个方法&#xff0c;在调用某一个方法时&#xff0c;可能就开启了一个Spring事务&#xff0c;那么在调用接下来的方法时&#xff0c;到底是共用…

【C++】二叉搜索树的原理及实现

简介 二叉搜索树(Binary Search Tree&#xff0c;BST)是一种常用的数据结构&#xff0c;本文将介绍二叉搜索树的原理与特性&#xff0c;并给出C代码实现&#xff0c;最后对其性能进行详细的分析。 文章目录 简介 一、二叉搜索树的概念 二、二叉搜索树的操作及实现 2、1 二叉搜…

01|Oracle学习(监听程序、管理工具、PL/SQL Developer、本地网络服务介绍)

基础概念 监听程序&#xff1a;运行在Oracle服务器端用于侦听客户端请求的程序。 相当于保安&#xff0c;你来找人&#xff0c;他会拦你&#xff0c;问你找谁。他去帮你叫人过来。 配置监听程序应用场景 Oracle数据库软件安装之后没有监听程序&#xff08;服务&#xff09;…