常见数据结构面试题目(四)

本文探讨了在二叉树中寻找所有节点值之和等于特定整数的路径的方法。介绍了三种不同的算法思路,包括记录所有路径再筛选、双向二元树改进以及递归加回溯的方法。

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

题目:

 输入一个整数和一棵二元树。从树的根结点开始往下访问一直到叶结点所经过的所有结点形成一条路径。打印出和与输入整数相等的所有路径。

        例如输入整数 22 ,如下图二元树:
                                            10
                                           /     \
                                          5     12
                                        /    \  
                                       4     7 

   则打印出两条路径:10, 12和10, 5, 7。

思路:

有三种方法:

(1)找出并记录下从根节点到叶子节点的所有路径,对每条路径进行尝试,找到路径上节点和为输入整数的路径。

(2)改造普通二元树为双向二元树,通过指针便可查找相邻的上下级节点。遍历二元树,可找到树上的叶子节点。满足条件路径是叶子到根节点路径的子集。由叶子节点向上查找,当路径上节点和为输入整数,并且到达跟节点时,此路径满足条件。

(3)此方法参考http://blog.youkuaiyun.com/dazhong159/article/details/7906916。算法中涉及递归和回溯。由根节点向叶子节点遍历,记录下遍历路径。当到达叶子节点,并且路径和为输入整数,则此路径满足条件;否则该路径自动废弃。

    方法一与方法二思路基本一致,遍历二元树找出所有全通路径,针对每一条计算经过节点的和,找到符合条件的路径。代码实现如下:

	//记录所有从根节点到叶子节点的路径
	private static List<List<Node>> paths=new ArrayList<List<Node>>();
	//获得所有到子节点的路线,记录到path中
	private static void getAllPaths(List<Node> path , Node node){
		path.add(node);
			
		if(node.getLeft() == null && node.getRight()==null){//node为叶子节点
			paths.add(path);
			return;
		}
		Node left = node.getLeft();
		if(left != null){
			List<Node> leftPath = new ArrayList<Node>();
			leftPath.addAll(path);
			getAllPaths(leftPath, left);
		}
		Node right = node.getRight();
		if(right !=null){
			List<Node> rightPath = new ArrayList<Node>();
			rightPath.addAll(path);
			getAllPaths(rightPath, right);
		}
	}
	//寻找路径上节点和为sum的路径
	private static void getCorrectPath(int sum){
		
		List<List<Node>> corPath = new ArrayList<List<Node>>();	
		for(List<Node> path : paths){
			int total = 0;
			for(Node node : path){
				total += node.getValue();
			}			
			if(total == sum){
				corPath.add(path);
			}
		}
		for(List<Node> path : paths){
			for(Node node :path){
				System.out.print(node.getValue() + "       ");
			}
			System.out.println();
		}
	}
     方法三核心代码如下:
//sum表示整数值,top为经过路径的节点个数,path用来存放路径节点。
//符合条件的路径满足两个条件:1)sum逐一减去经过节点值后为0。2)节点节点时叶子节点
void findPath(BiTreeNode *root, int sum,int top,int path[])  
{  
    path[top++] = root->data;  //所经过节点存入数据路径中
    sum -= root->data;  
      
    if (root->left == NULL && root->right==NULL)   
    {  
        if (sum == 0)   
        {  
            printPath(path, top);  //满足条件节点,输出路径
        }  
    }   
    else   
    {  
        if (root->left != NULL)   
            findPath(root->left, sum, top,path);  
        if (root->right!=NULL)   
            findPath(root->right, sum, top,path);  
    }  
    top --;  //回溯,当返回后,路径长度减一
    sum += root->data;  //sum值回溯
}  
    方法三成功利用递归函数返回特性,程序走完一条路径后,会自动返回分歧节点,沿另一条路径继续执行,由此可遍历完成所有根节点到叶子节点的路径。当回到分歧节点后,重点是恢复状态值,即sum与path值。此方法通过path记录所经过路径,且对于公共路径进行了重复利用。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值