分而治之
分而治之是算法设计中的一种方法,它将一个问题分成多个和原问题相似的小问题,递归解决小问题,再将结果合并以解决原来的问题。 应用场景:归并排序、快速排序。
leetcode:374 猜数字大小
/**
* 解题思路:二分搜索同样具备“分、解、合”的特性。这里我们考虑使用分而治之的思想。
* 解题步骤:
* 分:计算中间元素,分割数组。
* 解:递归的在较大或者较小子数组进行二分搜索。
*/
var guessNumber = function(n) {
const mainCode = (low, high) => {
//递归的结束点
if (low > high) {
return;
};
//获取到中间元素的下标
const mid = Math.floor((low + high) / 2);
const res = guess(mid);
//依次作出判断
if (res === 0) {
return mid;
} else if (res === -1) {
return mainCode(low, mid - 1);
} else {
return mainCode(mid + 1, high);
}
}
return mainCode(1, n);
};
leetcode 226 翻转二叉树
/**
* 解题思路:
* (1)先将左右子树互换位置,再将子树互换位置
* (2)符合“分、解、合”特性
*
* 解题步骤:
* (1)分:获取左右子树
* (2)解:递归的翻转左右子树
* (3)合:将翻转后的左右子树换个位置放到根节点上
*/
var invertTree = function(root) {
//如果根节点为空, 直接返回null
if(!root) {
return null;
}
return {
//每个根节点的值肯定是保持不变的
val: root.val,
//将递归好的右子树放在左边
left: invertTree(root.right),
//将递归好的左子树放在右边
right: invertTree(root.left)
}
/**
时间复杂度:O(n)
空间复杂度:O(n) 相当于二叉树的深度
*/
};
leetcode 100 相同的树
/**
* 解题思路:两个相同的树:根节点的值相同、左子树相同、右子树相同
* 解题步骤:
* (1)分:获取两个树的左右子树
* (2)解:递归的判断两个树的左右子树是否相同
* (3)合:将上述结果进行合并,如果根节点的值也相同,则两棵树相同
*/
var isSameTree = function(p, q) {
//左右子树如果为空,则两棵树相同,返回ture
if(!p && !q) {
return true;
}
//两棵树的根节点值、左右子树相同
if(p && q && p.val === q.val &&
isSameTree(p.left, q.left) &&
isSameTree(p.right, q.right)
) {
return true;
}
return false;
/**
时间复杂度:O(n)
空间复杂度:O(n)
*/
};
leetcode 101 对称二叉树
var isSymmetric = function(root) {
//如果根节点为空,直接返回true
if(!root) {
return true;
}
//将对称问题转为镜像问题
const isMirror = (l, r) => {
//递归的终点
if(!l && !r) {
return true;
}
if(l && r && l.val === r.val &&
isMirror(l.left, r.right) &&
isMirror(l.right, r.left)) {
return true;
}
//否则返回false
return false;
}
//调用一下
return isMirror(root.left, root.right);
/*
时间复杂度:O(n)
空间复杂度:O(n)
*/
};