递归算法学习——Path Sum系列

本文探讨了LeetCode中路径求和系列问题的解决方法,包括PathSum、PathSumⅡ及PathSumⅢ三个题目的算法实现。通过递归方式寻找二叉树中满足特定条件的路径。

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

一、递归

递归很重要的两个条件:

1)确定终止条件;

2)递归的过程。

两个条件都需要细致地分析问题的细节。


二、算法题

1、Path Sum ,LeetCode第112题(注意递归的终止条件)

问题描述:给出一棵二叉树以及一个数字sum,判断在这棵二叉树上是否存在一条从根到叶子的路径,其路径上所有节点为sum

class Solution {
    public boolean hasPathSum(TreeNode root, int sum) {
        if(root==null) return false;//如果传入的root为空,找不到对应子树
        //if(root==null) return sum==0;
        //该句是递归终止条件,确保root节点遍历到叶子节点。否则的话,使用上面一句,会有漏洞
        if(root.left==null && root.right==null) return sum==root.val;
        if(hasPathSum(root.left,sum-root.val))   return true;
        if(hasPathSum(root.right,sum-root.val))  return true;
        return false;
    }
}

注意,一定要到叶子节点才递归终止。判断条件是if(root.left==null && root.right==null)。

2、Path SumⅡ,Leetcode 113题。

class Solution {
    public List<List<Integer>> pathSum(TreeNode root, int sum) {
        List<List<Integer>> lists = new LinkedList<List<Integer>>();
        List<Integer> list = new LinkedList<Integer>();
        pathSum(root,sum,lists,list);
        return lists;
    }
    
    public void pathSum(TreeNode root,int sum,List<List<Integer>> lists,List<Integer> list){
        if(root==null) return;
        list.add(root.val);
        if(root.left==null && root.right==null && sum==root.val){//root为叶子节点,并且找到对应的值时,添加jieguo
            lists.add(new LinkedList(list));
            list.remove(list.size()-1);
            return;
        }else{
            pathSum(root.left,sum-root.val,lists,list);
            pathSum(root.right,sum-root.val,lists,list);
        }
        list.remove(list.size()-1);
    }
    
    
}

3、Path SumⅢ,leetcode第437题。

问题描述:给出一棵二叉树以及一个数字sum,判断在这棵二叉树上存在多少条路径,其路径上所有的节点和为Sum。注意:

1)路径不一定要起始于根节点,终止于叶子节点

2)路径可以从任意节点开始,但是只可以向下走。

class Solution {
    public int pathSum(TreeNode root, int sum) {
        if(root==null) return 0;
        int res = 0;
        res += findPath(root,sum);//路径包含root节点的数量
        res += pathSum(root.left,sum);//不包含root节点的路径数量,左边
        res += pathSum(root.right,sum);//不包含root节点的路径数量,右边
        return res;
    }
    
    public int findPath(TreeNode root,int sum){
        if(root==null) return 0;//无需找到叶子节点
        int res=0;
        if(root.val==sum) res++;
        
        res += findPath(root.left,sum-root.val);//前一句找到了一条路径,但是还可以继续向下搜寻
        res += findPath(root.right,sum-root.val);
        return res;
    }
}

### 关于梯度下降法与线性回归 #### 梯度下降法原理 梯度下降法是一种最优化算法,在机器学习和人工智能领域广泛应用,旨在通过递归方式逼近最小偏差模型[^1]。该方法特别适用于解决高维空间中的复杂问题。 对于特定的成本函数 \( J(\theta) \),梯度下降采用迭代形式逐步接近其全局或局部极小值位置[^2]。每次更新参数时都沿着当前点处负梯度方向移动一定步长(即学习率),从而使得目标函数逐渐减小直至收敛到最优解附近。 #### 线性回归及其应用 在线性回归场景下,可以通过调整权重向量 θ 来预测连续型因变量 y 的取值情况。具体来说就是找到一条直线使所有样本点到这条直线上距离平方之和最小化——这正是最小二乘估计所追求的目标之一[^3]。 当我们将上述过程抽象成数学表达式,则可以表示为: \[ h_\theta(x)=\theta_0+\theta_1x_1+...+\theta_nx_n \] 这里 \(h_{\theta}(x)\) 表示假设函数;\(n\) 是特征数量;而每个 \(x_i(i=1,..,n)\) 则代表输入数据集中对应维度上的属性值。 为了评估模型的好坏程度并指导后续改进工作,通常定义如下损失函数作为衡量标准: \[ J(\theta )=\frac{1}{m}\sum _{{i=1}}^{m}[h_{\theta }(x^{(i)})-y^{(i)}]^2 \] 其中 m 为训练集大小,上式反映了平均意义上实际观测值同理论计算所得之间的差距有多大。 #### 使用Python实现简单版的基于梯度下降的线性回归 下面给出一段简单的 Python 代码片段用于展示如何利用 NumPy 库完成一次完整的建模流程: ```python import numpy as np def compute_cost(X, y, theta): """ 计算代价函数 参数: X (numpy.ndarray): 输入矩阵. y (numpy.ndarray): 输出向量. theta (numpy.ndarray): 参数向量. 返回: float: 当前参数下的误差均方根. """ m = len(y) predictions = X.dot(theta) square_errs = (predictions - y)**2 return 1/(2*m)*np.sum(square_errs) def gradient_descent(X, y, theta, alpha, iterations): """ 执行批量梯度下降算法以获得最佳拟合参数 参数: X (numpy.ndarray): 输入矩阵. y (numpy.ndarray): 输出向量. theta (numpy.ndarray): 初始化后的参数向量. alpha (float): 学习速率. iterations (int): 迭代次数. 返回: tuple[numpy.ndarray, list[float]]: 更新后的参数以及每轮迭代后对应的代价历史记录. """ m = len(y) cost_history = [] for i in range(iterations): prediction = X.dot(theta) error = np.dot((prediction-y).T,X) delta_theta = -(alpha/m)*error.T # 更新参数 theta += delta_theta # 将本轮次的结果加入列表保存起来以便观察变化趋势 current_cost = compute_cost(X,y,theta) cost_history.append(current_cost) return theta,cost_history if __name__ == "__main__": data_path = 'F:\\python\\机器学习\\data\\梯度下降求解逻辑回归\\梯度下降\\data\\logireg_data.txt' raw_data = np.loadtxt(data_path, delimiter=',') X = raw_data[:, :-1] y = raw_data[:,-1:] # 添加偏置项列 ones_col = np.ones([X.shape[0],1]) X_b = np.hstack((ones_col,X)) initial_theta = np.zeros(X_b.shape[1]) learning_rate = 0.01 num_iterations = 1500 final_theta, costs = gradient_descent(X_b, y, initial_theta ,learning_rate,num_iterations ) print('最终得到的最佳拟合参数:',final_theta.ravel()) ``` 此段程序实现了从读入外部文件至执行批处理版本GD全过程,并打印出了最后寻优结束时刻各系数的具体数值。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值