1 回溯算法
伪代码
void backtrack(nums, i) {
if (i == nums.len) {
if (达到target) {
res +=1
return
}
}
for op in {+1, -1} {
选择 op* nums[i]
// 穷举nums[i+1]
backtrack(nums, i+1)
撤销选择
}
}
22 括号生成
数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。
题解:回溯算法
private void backTrack(char[] cur, int pos, List<String> res) {
if (pos >= cur.length) {
if (isValidParenthesis(cur)) {
res.add(String.valueOf(cur));
}
return;
}
cur[pos] = '(';
backTrack(cur, pos+1, res);
cur[pos] = ')';
backTrack(cur, pos+1, res);
}
// 判断括号是否有序
private boolean isValidParenthesis(char[] cur) {
int balance = 0;
int n = cur.length;
for (int i = 0; i < n; i++) {
if (balance < 0) {
return false;
}
if (cur[i] == '(') {
balance++;
} else {
balance--;
}
}
return (balance == 0);
}
注意字符数组char[] 转string:String.valueOf(cur)
93.复原IP地址
题目描述:有效 IP 地址 正好由四个整数(每个整数位于 0 到 255 之间组成,且不能含有前导 0),整数之间用 '.' 分隔。输入字符串s,输出所有可能有效IP地址。
题解:
//
static constexpr int SEG_COUNT = 4;
vector<int> segments;
vector<string> ans;
// segId IP编号,取值[0,1,2,3],segStart 搜索开始索引
void dfs(string s, int segId, int segStart) {
// 结束条件:IP段搜完
if (segId == SEG_COUNT) {
if (segStart == s.size()) {
string ipAddr;
for (int i = 0; i < SEG_COUNT; i++) {
ipAddr += to_string(segments[i]);
if (i != SEG_COUNT - 1) {
ipAddr += ".";
}
}
ans.push_back(ipAddr);
}
return;
}
// 结束条件:IP段未搜完,已遍历完s
if (segStart == s.size()) {
return;
}
// 特殊情况,不能含有前导0,遇到0元素,只能识别为0
if (s[segStart] == '0') {
segments[segId] = 0;
dfs(s, segId + 1, segStart + 1);
return;
}
// 一般情况
int addr = 0;
for (int i = segStart; i < s.size(); i++) {
addr = 10 * addr + (s[i] - '0');
if (addr > 0 && addr <= 0xFF) {
segments[segId] = (addr);
dfs(s, segId + 1, i+1);
} else {
break;
}
}
}
2 阶乘
172 阶乘后的零
思路:尾部零数量等于因子10的个数 -》因子5个数
25!因子5个数=25/5 + 25/25 = 6
125! 因子5个数=125/5 + 125/25 + 125/125 = 25 + 5+1 = 31
3 区间调度
最大不重叠区间子集
435 无重叠区间
思路:移除区间最小数 =》最多不相交区间数
452 用最少的箭头射爆气球
思路:等价于最多不相交区间数 注意点:边界重叠算 相交
Arrays.sort(points, (v1, v2) -> { // 大数比较,防止越界
if (v1[1] < v2[1]) {
return -1;
} else if (v1[1] > v2[1]) {
return 1;
} else {
return 0;
}
});
4 区间合并
TODO
5 二叉树
完全二叉树定义:每层都是紧凑靠左 满二叉树:每层都是满的
完全二叉树节点个数
普通二叉树O(N)
int countNodes(Node root) {
if (root == null) {
return 0;
}
return 1 + countNodes(root.left) + countNodes(root.right);
}
满二叉树 O(logN)
int h = 0;
while(root != null) {
root = root.left;
h++;
}
return (Math.pow(2, h) -1);
6 高效寻找缺失、重复字符
解法1:hashmap 记录次数,空间 O(N)
解法2:dup、miss