题目地址:
https://www.lintcode.com/problem/find-the-missing-number-ii/description
给定一个正整数 n n n,和一个由数字组成的字符串 s s s。题目保证 s s s存在一种分割,使得每个部分都是 [ 1 , n ] [1,n] [1,n]之间的整数,并且一一对应,但是独缺某一个数。求出这个数。题目保证 n ≤ 30 n\le 30 n≤30。
思路是DFS。从字符串的某个位置开始,尝试切出一个一位数或者两位数,同时用一个boolean数组记录 1 ∼ n 1\sim n 1∼n中的哪些数已经取过。如果切出的数已经取过则略过,否则将其标记为取过,进入下一层递归。因为题目确保有解,所以当枚举到字符串最后的时候就说明枚举完了,最后只需将未标记为取过的数返回即可。代码如下:
public class Solution {
/**
* @param n: An integer
* @param str: a string with number from 1-n in random order and miss one number
* @return: An integer
*/
public int findMissing2(int n, String str) {
// write your code here
boolean[] visited = new boolean[n + 1];
dfs(str, n, 0, visited);
for (int i = 1; i <= n; i++) {
if (!visited[i]) {
return i;
}
}
return -1;
}
// 从s的下标为pos的地方开始枚举
private boolean dfs(String s, int n, int pos, boolean[] visited) {
// 如果pos到了字符串末尾,说明枚举成功,返回true
if (pos == s.length()) {
return true;
}
// 如果开始枚举的数是0,非法,直接返回false
if (s.charAt(pos) == '0') {
return false;
}
// 按照分割数的位数循环,长度只能是1或者2
for (int i = pos + 1; i <= Math.min(pos + 2, s.length()); i++) {
// 分割出枚举的数字
int num = Integer.parseInt(s.substring(pos, i));
// 如果数字没越界,并且之前没取过,说明可以枚举,标记其为取过后进入下一层递归
if (0 < num && num <= n && !visited[num]) {
visited[num] = true;
if (dfs(s, n, i, visited)) {
return true;
}
visited[num] = false;
}
}
return false;
}
}
时间复杂度 O ( 2 l ) O(2^l) O(2l),空间复杂度 O ( n ) O(n) O(n)。
本文介绍了一种使用深度优先搜索(DFS)算法解决寻找缺失数字问题的方法。给定一个包含1到n之间数字的字符串,其中缺少一个数字,通过递归地分割字符串并检查已访问数字状态来找到缺失的数字。
7252

被折叠的 条评论
为什么被折叠?



