最长连续递增子序列[如何将循环改成递归,高效执行。]

前言

递归代码简洁,有着高效的执行效率。本文通过算法–最长连续递增子序列,来锻炼分析并拆解问题,再将拆解出的相同子问题进行递归改写。

一、最长连续递增子序列

在这里插入图片描述

二、循环与递归

1、双指针循环

// 最长连续递增序列。
public class FindLengthOfLCIS {
    /*
    target:寻找最长连续递增子序列。
    如何确定连续子序列?用指针确定起点和端点即可确定一个子序列。
    如何保证递增?保证前驱小于后继,根据传递性,那么该子序列为递增子序列。
    如何求最长?通过一个端点指针减去起点指针,即可得到一个子序列长度,用一个变量记录最长长度,在寻找满足条件的子序列过程中,不断更新它即可。
     */
    public int findLengthOfLCIS(int[] nums) {
        // 初始化起始指针位置。
        int begin = 0, end = 1;
        int max = 0;// 初始化最长子序列长度。
        int gap = 0;// 子序列的长度。
        while (end < nums.length) {
            // 不递增的情况。
            if (nums[end] <= nums[end - 1]) {
                // 更新最长子序列长度。
                gap = end - begin;
                if (max < gap) max = gap;
                // 更新下一个子序列的起始节点。
                begin = end;
            }
            // 递增 或者 不递增,都需要往后遍历。
            ++end;
        }
        // 当循环结束之后,还有最后一个递增子序列需要比较一下长度。
        gap = end - begin;
        if (max < gap) max = gap;
        // 返回最终找到的最大子序列长度。
        return max;

    }
}

2、双指针递归

// 一题多解,开拓视野。采用简洁的递归来完成。
class FindLengthOfLCIS2 {
    /*
    target:寻找最长连续递增子序列。
    如何确定连续子序列?用指针确定起点和端点即可确定一个子序列。
    如何保证递增?保证前驱小于后继,根据传递性,那么该子序列为递增子序列。
    如何求最长?通过一个端点指针减去起点指针,即可得到一个子序列长度,用一个变量记录最长长度,在寻找满足条件的子序列过程中,不断更新它即可。
     */
    public int findLengthOfLCIS(int[] nums) {
        return findLengthOfLCIS(nums, 0, 1);
    }

    /**
     * 双指针 + 递归,递归完成最大子序列长度的判断与获取。
     * @param nums 原数组。
     * @param begin 起始指针。
     * @param end 结尾指针。
     * @return 最长子序列长度,当然递归出口返回最后一个子序列长度即可。
     */
    private int findLengthOfLCIS(int[] nums, int begin, int end) {
        // 递归确定最长递增子序列。
        while (end < nums.length) {
            // 子序列确定以后,就开始递归比较谁是最长子序列。
            if (nums[end] <= nums[end - 1]) return Math.max(end - begin, findLengthOfLCIS(nums, end, end + 1));
            // 还未能确定当前连续递增子序列。
            ++end;
        }
        // while正常结束,递归也结束了,返回最后一个连续递增子序列长度。
        return end - begin;
    }
}

总结

1)问题拆解,双指针问题。
2)独立相同子问题,可进行递归改写,高效执行。

参考文献

[1] LeetCode 最长连续递增子序列

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值