最大上升子串的MATLAB程序实现

本文介绍了一种寻找数组中最长严格上升子序列的算法实现过程,并通过具体例子详细解释了算法步骤。该算法利用辅助数组记录每个位置的最长上升子序列长度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

cody上有个最长字串问题,比如,数组,x = [8, 24, 7, 35, 23, 52, 39, 64, 78], 最长的严格上升字串为[8, 24, 35, 52, 64, 78],  长度为6

这个题目我个人的做法是,构造一个辅助的数组y, y的第i个元素表示,x的第1个元素到x的第i个元素之间,最大的上升字串的长度,关键就是下一步的思路

那么y的第i+1个元素的,就是x的1到i的元素中那些小于x的第i+1个元素的辅助数组对应的y的值加1.

假设i=4,我们可以看到

y(1) = 1, 对应的子串为8

y(2) = 2, 对应的子串为[8, 24]

y(3) = 1, 对应的子串为7 

y(4)= 3, 对应的子串为[8 24 35]

 

那么当i=5的时候,第5个元素会接在那个字串后面会使得该字串最大呢?

首先要根据上升要求,因为第5个元素是23, 只能接在8, 7的后面,因为这两个数都小于23, 而24和35不行

那么应该接在8和7哪个后面才能形成最长的字串呢,我们要看当前这两个串谁最长,就接在谁的后面,

这三个字串的长度分别是1,1,一样长,应该谁后面都行,长度等于该子串的长度加1

y(5) = 2, 对应子串为[8 23]

 

y数组的最后一个值

对于上述这个问题,我们一步一步来看一个,我们遍历来求出y数组的元素,首先初始化

y = [1 0 0 0 0 0 0 0 0]

第一步, i = 2

x=24, 2之前只有1, 而且x(1)<x(2), 因此y(2) = y(1) + 1;

y = [1 2 0 0 0 0 0 0 0]

第二步,i=3

x=7, 之前的x(1:2)没有元素小于7,那么y(3) = 1, 因为从自己开始,自己是第一个

第三步, i = 4

x= 35, 之前的x(1:3)中有三个元素都小于35, 其中最长的是y(2)=2, 因为y(4) = y(2)+1=2

...

还是写个程序来说明下吧

function demo_algorithm(x)
fprintf("创建辅助数组y,y的第i个元素表示:\n" + ...
    "从x第一个元素到x的第i个元素所形成的序列中" + ...
    "最长上升字串长度\n" + ...
    "y的第一个元素为1");
y = [1, zeros(1,numel(x)-1)];
fprintf("辅助数组y从2开始遍历\n");
for i = 2 : numel(y)
    fprintf("第%d步, i = %d\n",i-1, i);
    fprintf("x的1至%d的元素为%s\n",i, mat2str(x(1:i)));
    idx = find(x(1:i-1)<x(i));
    if isempty(idx)
        fprintf("没有元素小于x(%d)\n",i);
        y(i) = 1;
        fprintf("y(%d)=1\n\n",i);        
    else
        fprintf("其中第%s号元素小于x(%d)\n",mat2str(idx),i);
        [maxv, maxi] = max(y(idx));
        fprintf("其中第%d号元素对用的字串最长为%d\n",idx(maxi),maxv);
        y(i) = maxv + 1;
        fprintf("y(%d)=y(%d)+1;\n",i,idx(maxi));
        fprintf("y:%s\n\n",mat2str(y));
    end
end
fprintf("最长字串长度为%d",y(end));
end
x = [8, 24, 7, 35, 23, 52, 39, 64, 78]
demo_algorithm(x)

 

运行结果如下:

创建辅助数组y,y的第i个元素表示:
从x第一个元素到x的第i个元素所形成的序列中最长上升字串长度
y的第一个元素为1

辅助数组y从2开始遍历

第1步, i = 2
x的1至2的元素为[8 24]
其中第1号元素小于x(2)
其中第1号元素对用的字串最长为1
y(2)=y(1)+1;
y:[1 2 0 0 0 0 0 0 0]

第2步, i = 3
x的1至3的元素为[8 24 7]
没有元素小于x(3)
y(3)=1

第3步, i = 4
x的1至4的元素为[8 24 7 35]
其中第[1 2 3]号元素小于x(4)
其中第2号元素对用的字串最长为2
y(4)=y(2)+1;
y:[1 2 1 3 0 0 0 0 0]

第4步, i = 5
x的1至5的元素为[8 24 7 35 23]
其中第[1 3]号元素小于x(5)
其中第1号元素对用的字串最长为1
y(5)=y(1)+1;
y:[1 2 1 3 2 0 0 0 0]

第5步, i = 6
x的1至6的元素为[8 24 7 35 23 52]
其中第[1 2 3 4 5]号元素小于x(6)
其中第4号元素对用的字串最长为3
y(6)=y(4)+1;
y:[1 2 1 3 2 4 0 0 0]

第6步, i = 7
x的1至7的元素为[8 24 7 35 23 52 39]
其中第[1 2 3 4 5]号元素小于x(7)
其中第4号元素对用的字串最长为3
y(7)=y(4)+1;
y:[1 2 1 3 2 4 4 0 0]

第7步, i = 8
x的1至8的元素为[8 24 7 35 23 52 39 64]
其中第[1 2 3 4 5 6 7]号元素小于x(8)
其中第6号元素对用的字串最长为4
y(8)=y(6)+1;
y:[1 2 1 3 2 4 4 5 0]

第8步, i = 9
x的1至9的元素为[8 24 7 35 23 52 39 64 78]
其中第[1 2 3 4 5 6 7 8]号元素小于x(9)
其中第8号元素对用的字串最长为5
y(9)=y(8)+1;
y:[1 2 1 3 2 4 4 5 6]

最长字串长度为6

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值