[LintCode] Find the Missing Number II

Giving a string with number from 1 to n in random order, but miss 1 number.Find that number.

You can assume n <= 30

Example

Given n = 20, str = 19201234567891011121314151618

return 17

Solution 1. DFS

Algorithm.

1. set a 1D boolean array: exist[0........n] to track a number from 1 to n is found or not.

2. starting from index i, get 2 digits d1 and d2 and do the following in order.

  a. d1 == 0:  return false for invalid split;

  b. d1 != 0 && exist[d1] == false:   get a valid unchecked 1 digit number, set exist[d1] to true and keep searching from index i + 1;

    if the searching from i + 1 returns true, then the current search from i also returns true;

    if it returns false, backtrack exist[d1] to false and proceed to case c.

  c. d <= n && exist[d] == false:  get a valid unchecked 2 digits numbers, set exist[d] to true and keep searching from index i + 2;

      if the searching from i + 2 returns true, then the current search from i also returns true;

   if it returns false, backtrack exist[d] to false and the current search from i returns false as we‘ve already exhausted all possible

      splits without finding a valid split.

3. After the search from index 0 finishes, the boolean array exist is correctly updated. Scan from index 1 to n and find the index k where exist[k] = false.

Return k as the missing number.

 1 public class Solution {
 2     /**
 3      * @param n an integer
 4      * @param str a string with number from 1-n
 5      *            in random order and miss one number
 6      * @return the missing integer
 7      */
 8     public int findMissing2(int n, String str) {
 9         if(n < 1 || str == null){
10             return 0;
11         }
12         boolean[] exist = new boolean[n + 1];
13         for(int i = 0; i <= n; i++){
14             exist[i] = false;
15         }
16         dfs(str, 0, exist, n);
17         int val = 1;
18         for(; val <= n; val++){
19             if(!exist[val]){
20                 break;
21             }
22         }
23         return val;
24     }
25     private boolean dfs(String str, int startIdx, boolean[] exist, int maxNum){
26         if(startIdx >= str.length()){
27             return true;
28         }
29         if(startIdx == str.length() - 1){
30             int d = str.charAt(startIdx) - ‘0‘;
31             if(d == 0 || exist[d]){
32                 return false;
33             }
34             else{
35                 exist[d] = true;
36                 return true;
37             }
38         }
39         int d1 = str.charAt(startIdx) - ‘0‘;
40         int d2 = str.charAt(startIdx + 1) - ‘0‘;
41         int d = d1 * 10 + d2;
42         //first digit is 0, no valid way to keep searching
43         if(d1 == 0){
44             return false;
45         }
46         //can get a valid unchecked 1 digit number
47         if(!exist[d1]){
48             exist[d1] = true;
49             if(dfs(str, startIdx + 1, exist, maxNum)){
50                 return true;
51             }
52             exist[d1] = false;
53         }
54         //can get a valid unchecked 2 digits number
55         if(d <= maxNum && !exist[d]){
56             exist[d] = true;
57             if(dfs(str, startIdx + 2, exist, maxNum)){
58                 return true;
59             }
60             exist[d] = false;
61         }
62         //can‘t get either a 1 or 2 digits unchecked number
63         return false;
64     }
65 }

To correctly get the missing number,  we should check the possiblity of splitting 1 digit before checking splitting 2 digits. Swaping the order of these

two steps yields incorrect answer. The reason for this is discussed in solution 2.

Solution 2. DFS

Solution 1 uses the condition n <= 30, so when deciding whether keep searching, it only checks the next 2 digits.  The disadvantage of this solution

is that it does not extend well if n is changed to more than 2 digits.

Solution 2 does not use the condition that n can have at most 2 digits, so it is a better in this matter.

The algorithm of this solution is as follows.

1. starting from the current digit, check if it is 0; if it is 0, return as we hit an invalid splitting.

2. if it is not 0 and <= n, set its checked flag to true and keep searching starting from the next digit.

3. after done searching, backtrack the current number‘s checked flag to false.

4. include the next digit to the current number; repeat steps 2 and 3 until the current number is > n.

Important note:

To get the correct result, a found boolean flag must be used to make sure a correct answer does not

get overwritten by an incorrect answer.

For example, str = "1234567891011" and n = 12.

The only right split is {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11} and the missing integer is 12;

Another split of {12, 3, 4, 5, 6, 7, 8, 9, 10, 11} also reaches the end of str since each splitted number is

in [1, 12].  However, this is not a right split as there are two missing numbers 1 and 2, which contradicts

the problem assumption. Any wrong splits that can reach the end of str always has at least two missing

numbers.

At some point, if splitting one digit and two digits can both reach the end of str, the one digit split is

always the right split and it always set the final answer first.  As a result, this solution uses a boolean flag

to ensure only the first reach of str‘s end updates the final answer.

 1 public class Solution {
 2     private boolean found = false;
 3     private int ans = 0;
 4     public int findMissing2(int n, String str) {
 5         boolean[] exist = new boolean[n + 1];
 6         dfs(0, n, str, exist);
 7         return ans;
 8     }
 9
10     private void dfs(int startIdx, int maxNum, String s, boolean[] exist) {
11         if (startIdx >= s.length()) {
12             if(!found){
13                 for (int k = 1; k <= maxNum; k++) {
14                     if (!exist[k]) {
15                         ans = k;
16                         break;
17                     }
18                 }
19                 found = true;
20             }
21             return;
22         }
23         int sum = s.charAt(startIdx) - ‘0‘;
24         if (sum == 0) {
25             return;
26         }
27         while (sum <= maxNum) {
28             if (!exist[sum]) {
29                 exist[sum] = true;
30                 dfs(startIdx + 1, maxNum, s, exist);
31                 exist[sum] = false;
32             }
33             startIdx++;
34             if (startIdx >= s.length()) {
35                 break;
36             }
37             sum = sum * 10 + (s.charAt(startIdx) - ‘0‘);
38         }
39     }
40 }

Related Problems

Decode Ways

Find the Missing Number

时间: 2024-12-27 07:34:48

[LintCode] Find the Missing Number II的相关文章

[LintCode] Find the Missing Number 寻找丢失的数字

Given an array contains N numbers of 0 .. N, find which number doesn't exist in the array. Example Given N = 3 and the array [0, 1, 3], return 2. Challenge Do it in-place with O(1) extra memory and O(n) time. 这道题是LeetCode上的原题,请参见我之前的博客Missing Number

Lintcode: Majority Number II 解题报告

Majority Number II 原题链接: http://lintcode.com/en/problem/majority-number-ii/# Given an array of integers, the majority number is the number that occurs more than 1/3 of the size of the array. Find it. Note There is only one majority number in the arra

Single Number,Single Number II

Single Number Total Accepted: 103745 Total Submissions: 218647 Difficulty: Medium Given an array of integers, every element appears twice except for one. Find that single one. Note:Your algorithm should have a linear runtime complexity. Could you imp

[LeetCode] Missing Number 丢失的数字

Given an array containing n distinct numbers taken from 0, 1, 2, ..., n, find the one that is missing from the array. For example, Given nums = [0, 1, 3] return 2. Note: Your algorithm should run in linear runtime complexity. Could you implement it u

136. Single Number &amp;&amp; 137. Single Number II &amp;&amp; 260. Single Number III

136. Single Number Given an array of integers, every element appears twice except for one. Find that single one. Note:Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory? Subscribe to see which co

1245 - Harmonic Number (II)(规律题)

1245 - Harmonic Number (II)   PDF (English) Statistics Forum Time Limit: 3 second(s) Memory Limit: 32 MB I was trying to solve problem '1234 - Harmonic Number', I wrote the following code long long H( int n ) {     long long res = 0;     for( int i =

LeetCode172 Factorial Trailing Zeroes. LeetCode258 Add Digits. LeetCode268 Missing Number

数学题 172. Factorial Trailing Zeroes Given an integer n, return the number of trailing zeroes in n!. Note: Your solution should be in logarithmic time complexity. (Easy) 分析:求n的阶乘中末位0的个数,也就是求n!中因数5的个数(2比5多),简单思路是遍历一遍,对于每个数,以此除以5求其因数5的个数,但会超时. 考虑到一个数n比他小

leetcode Ugly Number II

题目连接 https://leetcode.com/problems/ugly-number-ii/ Ugly Number II Description Write a program to find the $n_{th}$ ugly number. Ugly numbers are positive numbers whose prime factors only include $2, 3, 5.$ For example,$ 1, 2, 3, 4, 5, 6, 8, 9, 10, 12

leetcode Missing Number

题目连接 https://leetcode.com/problems/missing-number/ Missing Number Description Given an array containing n distinct numbers taken from$ 0, 1, 2, ..., n$, find the one that is missing from the array. For example,Given nums = $[0, 1, 3]$ return $2$. Not