LeetCode《程序员面试金典》面试题 04.12. 求和路径

2021/8/21 18:20:09 浏览：

• 题目
• 解题
• 解题一：蛮力法
• 解题二：优化算法

解题

解题一：蛮力法

// javascript
var pathSum = function(root, sum) {
if (root == null) return 0;
// 对从 root 开始，符合目标和的路径进行计数
let pathsFromRoot = countPathsWithSumFromNode(root, sum);
// 尝试左节点和右节点
let pathsOnLeft = pathSum(root.left, sum);
let pathsOnRight = pathSum(root.right, sum);
return pathsFromRoot + pathsOnLeft + pathsOnRight;
};

// 返回从该节点开始，符合目标和的路径的条数
var countPathsWithSumFromNode = function(node, targetSum) {
if (node == null) return 0;
let totalPaths = 0;
if (node.val === targetSum) { // 找到一条从 root 开始的路径
totalPaths++;
}
totalPaths += countPathsWithSumFromNode(node.left, targetSum - node.val);
totalPaths += countPathsWithSumFromNode(node.right, targetSum - node.val);
return totalPaths;
};


解题二：优化算法

// javascript
var pathSum = function(root, sum) {
return countPathWithSum(root, sum, 0, new Map());
};

var countPathWithSum = function(root, targetSum, cumSum, record) {
if (root === null) return 0; // 基础情况

cumSum += root.val;
let sum = cumSum - targetSum;
// 对终止于该节点，符合目标和的路径进行计数
// let totalPaths = record[sum] ? record[sum] : 0;
let totalPaths = record.has(sum) ? record.get(sum) : 0;

// 如果 runningSum 等于 targetSum，则发现一条从 root 开始的新路径。加上这条路径
if (cumSum === targetSum) totalPaths++;

// 对 pathCount 加 1，递归，对 pathCount 减 1
increateHashTable(record, cumSum, 1);
totalPaths += countPathWithSum(root.left, targetSum, cumSum, record);
totalPaths += countPathWithSum(root.right, targetSum, cumSum, record);
increateHashTable(record, cumSum, -1);
return totalPaths;
}

var increateHashTable = function(record, cumSum, delta) {
// if (record[cumSum]) record[cumSum] += delta;
if (record.has(cumSum) === true) record.set(cumSum, record.get(cumSum) + delta);
// else record[cumSum] = delta;
else record.set(cumSum, delta);
// if (record[cumSum] === 0) record.delete(cumSum);
if (record.get(cumSum) === 0) record.delete(cumSum);
}


1. has 要搭配 getset 使用，假设是用 record[0] = 1record.has(0)false，应该用 if (record[0]) 进行判断；
2. record[0] = 1 设置值时，如果用 for (let key in record) 来遍历，key 的类型是 字符串，如果要进行加法运算，比如 let newKey = key + 1，应该写成 let newKey = key - 0 + 1。因为 字符串加法会隐式转换后面的值，最后变成字符串拼接