#include <iostream>
using namespace std;
const int N = 15;
int ret;
int n;
bool vis[N];
int arr[N];
void dfs(int pos)
{
if(pos == n + 1) // 找到⼀种合法⽅案 {
ret++;
return;
}
for(int i = 1; i <= n; i++)
{
if(vis[i]) continue; // 当前 i 已经放过了 - 剪枝
if(vis[arr[i]]) return; // 剪枝
vis[i] = true; // 相当于放上 i 号队员 dfs(pos + 1);
vis[i] = false; // 回溯- 还原现场 }
}
int main()
{
cin >> n;
for(int i = 1; i <= n; i++) cin >> arr[i];
dfs(1);
cout << ret << endl;
return 0;
}
java算法代码:
java复制代码
mport java.util.*;
public class Main
{
public static int N = 15; public static int n, ret; public static boolean[] vis = new boolean[N]; public static int[] arr = new int[N]; public static void dfs(int pos) {
if(pos == n + 1) // 找到⼀种合法情况 {
ret++;
return;
}
for(int i = 1; i <= n; i++)
{
if(vis[i] == true) continue; // 剪枝 - i 号队员已经放过了
if(vis[arr[i]]) return; // 剪枝
vis[i] = true; // 相当于已经放上 i 号队员 dfs(pos + 1);
vis[i] = false; // 回溯 - 恢复现场 } }
public static void main(String[] args)
{
Scanner in = new Scanner(System.in); n = in.nextInt(); for(int i = 1; i <= n; i++)
{
arr[i] = in.nextInt();
}
dfs(1);
System.out.println(ret);
}
}
数据范围:节点数满足 1 \le n \le 10^51≤n≤105 ,节点上的值满足 |val| \le 1000∣val∣≤1000
要求:空间复杂度 O(1)O(1),时间复杂度 O(n)O(n)
示例1
输入:
{1,2,3}
复制返回值:
6
复制
示例2
输入:
{-20,8,20,#,#,15,6}
复制返回值:
41
复制说明:
其中一条最大路径为:15=>20=>6,路径和为15+20+6=41
示例3
输入:
{-2,#,-3}
返回值:
-2
讲解算法原理
解法:
算法思路:
树形dp:
a. 左⼦树收集:以左⼦树为起点的最⼤单链和;b. 右⼦树收集:以右⼦树为起点的最⼤单链和;
c. 根节点要做的事情:整合左右⼦树的信息,得到经过根节点的最⼤路径和;
d. 向上返回:以根节点为起点的最⼤单链和
编写代码
c++算法代码:
cpp复制代码
class Solution
{
public:
int ret = -1010;
int maxPathSum(TreeNode* root)
{
dfs(root);
return ret;
}
int dfs(TreeNode* root)
{
if(root == nullptr) return 0;
int l = max(0, dfs(root->left));// 左⼦树的最⼤单链和 int r = max(0, dfs(root->right)); // 右⼦树的最⼤单链和 // 经过root的最⼤路径和
ret = max(ret, root->val + l + r);
return root->val + max(l, r);
}
};
java算法代码:
java复制代码
import java.util.*;
/*
* public class TreeNode {
* int val = 0;
* TreeNode left = null;
* TreeNode right = null;
* public TreeNode(int val) {
* this.val = val;
* }
* }
*/
public class Solution
{
int ret = -1010;
public int maxPathSum (TreeNode root)
{
dfs(root);
return ret;
}
int dfs(TreeNode root)
{
if(root == null) return 0;
int l = Math.max(0, dfs(root.left)); // 左⼦树为根的最⼤单链和 int r = Math.max(0, dfs(root.right)); // 右⼦树为根的最⼤单链和 // 经过root的最⼤路径和
ret = Math.max(ret, root.val + l + r);
return root.val + Math.max(l, r);
}
}