Woodstock Blog

a tech blog for general algorithmic interview questions

[LeetCode 4] Median of Two Sorted Arrays

Question

link

There are two sorted arrays A and B of size m and n respectively. Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).

Stats

Frequency 3
Diffficulty 5
Adjusted Difficulty 5
Time to use --------

Ratings/Color = 1(white) 2(lime) 3(yellow) 4/5(red)

Analysis

This is a tough question.

If the size of the 2 arrays (i.e. m and n) are same, this would become a much easier question with simple “Divide and Conquer” solution. Well, not extremely easy like everyone can solve it, but a much simpler one. I do recommend you to read more at this post before you procceed.

However, this question is not as simple. Let’s talk about it.

Solution

This first solution is well covered in the MIT CLRS handouts. The basic idea is, finding the median of the first array, then assuming this number is the final median, and look where this element should have been put in the second array. There are 3 possible conditions. For example, if the arrays are {1, 4, 5, 6, 26} and {2, 13, 34}. We first get number 5, and compare it with 13. Then we know that median shall be large than 5, and we continue this (like) binary search with O(lgn) complexity. This solution is complex and difficult in thinking. I would like to focus on a different solution.

Second solution, credit goes to ninechap. Finding the median is like finding the (k)th element from the combination of 2 arrays. We might have to search for (k)th element twice, but the overall complexity is always O(lg n).

My code

public class Solution {
    public double findMedianSortedArrays(int A[], int B[]) {
        if (A == null || B == null) {
            return 0;
        }
        int len = A.length + B.length;
        int mid1 = (len + 1) / 2;
        int mid2 = len / 2 + 1;
        // there are chances the mid1 == mid2, (i.e. when odd elements) 
        // for simplicity of the code, leave it this way. I admit I'm lazy. 
        return ((double) getKth(A, B, 0, 0, mid1) 
                + getKth(A, B, 0, 0, mid2)) / 2;
    }

    private int getKth(int A[], int B[], int start1, int start2, int k) {
        // note that k start from 1, not from 0
        int len1 = A.length;
        int len2 = B.length;
        if (start1 >= len1) {
            // all elements in A is used up.
            return B[start2 + k - 1];
        } else if (start2 >= len2) {
            return A[start1 + k - 1];
        }
        // now both A and B have elements left
        if (k == 1) {
            return Math.min(A[start1], B[start2]);
        } else {
            // eliminate half of k. Since k >=2: 
            int half = k / 2;
            int mid1 = start1 + half - 1;
            int mid2 = start2 + half - 1;
            // this is the critical part. We now have mid1 and mid2
            // and we try to eliminate all element to the left of
            // either mid1 or mid2 (inclusively)
            // so what I need is to compare the value of A[mid1] and B[mid2]
            int val1 = Integer.MAX_VALUE;
            if (mid1 < len1) {
                val1 = A[mid1];
            }
            int val2 = Integer.MAX_VALUE;
            if (mid2 < len2) {
                val2 = B[mid2];
            }
            // this is another important point. mid1 and mid2 may be out of bound
            // if so, the value should be MAX_VALUE because median could not fall on the other array
            // why? draw it yourself and you'll see. I can't explain without a picture. 
            if (val1 > val2) {
                // discard mid2 and all elements to the left of it. 
                return getKth(A, B, start1, mid2 + 1, k - half);
            } else {
                return getKth(A, B, mid1 + 1, start2, k - half);
            }
        }
    }
}

Note: starting from today, I would post my code with more focus on readability, instead of conciseness. Sometimes, the former is much more important than the latter.

LeetCode Statistics

LeetCode Statistics

link

ID Question Diff Freq Data Structure Algorithms
             

1 Two Sum 2 5 array sort

        set Two Pointers

2 Add Two Numbers 3 4 linked list Two Pointers

          Math

3 Longest Substring Without Repeating Characters 3 2 string Two Pointers

        hashtable  

4 Median of Two Sorted Arrays 5 3 array Binary Search

5 Longest Palindromic Substring 4 2 string  

6 ZigZag Conversion 3 1 string  

7 Reverse Integer 2 3   Math

8 String to Integer (atoi) 2 5 string Math

9 Palindrome Number 2 2   Math

10 Regular Expression Matching 5 3 string Recursion

          DP

11 Container With Most Water 3 2 array Two Pointers

12 Integer to Roman 3 4   Math

13 Roman to Integer 2 4   Math

14 Longest Common Prefix 2 1 string  

15 3Sum 3 5 array Two Pointers

16 3Sum Closest 3 1 array Two Pointers

17 Letter Combinations of a Phone Number 3 3 string DFS

18 4Sum 3 2 array  

19 Remove Nth Node From End of List 2 3 linked list Two Pointers

20 Valid Parentheses 2 5 string Stack

21 Merge Two Sorted Lists 2 5 linked list sort

          Two Pointers

          merge

22 Generate Parentheses 3 4 string DFS

23 Merge k Sorted Lists 3 4 linked list sort

        heap Two Pointers

          merge

24 Swap Nodes in Pairs 2 4 linked list  

25 Reverse Nodes in k-Group 4 2 linked list Recursion

          Two Pointers

26 Remove Duplicates from Sorted Array 1 3 array Two Pointers

27 Remove Element 1 4 array Two Pointers

28 Implement strStr() 4 5 string Two Pointers

          KMP

          rolling hash

29 Divide Two Integers 4 3   Binary Search

          Math

30 Substring with Concatenation of All Words 3 1 string Two Pointers

31 Next Permutation 5 2 array permutation

32 Longest Valid Parentheses 4 1 string DP

33 Search in Rotated Sorted Array 4 3 array Binary Search

34 Search for a Range 4 3 array Binary Search

35 Search Insert Position 2 2 array  

36 Valid Sudoku 2 2 array  

37 Sudoku Solver 4 2 array DFS

38 Count and Say 2 2 string Two Pointers

39 Combination Sum 3 3 array combination

40 Combination Sum II 4 2 array combination

41 First Missing Positive 5 2 array sort

42 Trapping Rain Water 4 2 array Two Pointers

          Stack

43 Multiply Strings 4 3 string Two Pointers

          Math

44 Wildcard Matching 5 3 string Recursion

          DP

          greedy

45 Jump Game II 4 2 array  

46 Permutations 3 4 array permutation

47 Permutations II 4 2 array permutation

48 Rotate Image 4 2 array  

49 Anagrams 3 4 string  

        hashtable  

50 Pow(x, n) 3 5   Binary Search

          Math

51 N-Queens 4 3 array DFS

52 N-Queens II 4 3 array DFS

53 Maximum Subarray 3 3 array DP

54 Spiral Matrix 4 2 array  

55 Jump Game 3 2 array  

56 Merge Intervals 4 5 array sort

        linked list merge

        red-black tree  

57 Insert Interval 4 5 array sort

        linked list merge

        red-black tree  

58 Length of Last Word 1 1 string  

59 Spiral Matrix II 3 2 array  

60 Permutation Sequence 5 1   permutation

          Math

61 Rotate List 3 2 linked list Two Pointers

62 Unique Paths 2 3 array DP

63 Unique Paths II 3 3 array DP

64 Minimum Path Sum 3 3 array DP

65 Valid Number 2 5 string Math

66 Plus One 1 2 array Math

67 Add Binary 2 4 string Two Pointers

          Math

68 Text Justification 4 2 string  

69 Sqrt(x) 4 4   Binary Search

70 Climbing Stairs 2 5   DP

71 Simplify Path 3 1 string Stack

72 Edit Distance 4 3 string DP

73 Set Matrix Zeroes 3 5 array  

74 Search a 2D Matrix 3 3 array Binary Search

75 Sort Colors 4 2 array sort

          Two Pointers

76 Minimum Window Substring 4 2 string Two Pointers

77 Combinations 3 4   combination

78 Subsets 3 4 array Recursion

          combination

79 Word Search 3 4 array DFS

80 Remove Duplicates from Sorted Array II 2 2 array Two Pointers

81 Search in Rotated Sorted Array II 5 3 array Binary Search

82 Remove Duplicates from Sorted List II 3 3 linked list Recursion

          Two Pointers

83 Remove Duplicates from Sorted List 1 3 linked list  

84 Largest Rectangle in Histogram 5 2 array Stack

85 Maximal Rectangle 5 1 array DP

          Stack

86 Partition List 3 3 linked list Two Pointers

87 Scramble String 5 2 string Recursion

          DP

88 Merge Sorted Array 2 5 array Two Pointers

          merge

89 Gray Code 4 2   combination

90 Subsets II 4 2 array Recursion

          combination

91 Decode Ways 3 4 string Recursion

          DP

92 Reverse Linked List II 3 2 linked list Two Pointers

93 Restore IP Addresses 3 3 string DFS

94 Binary Tree Inorder Traversal 4 3 tree Recursion

        hashtable morris

          Stack

95 Unique Binary Search Trees II 4 1 tree DP

          DFS

96 Unique Binary Search Trees 3 1 tree DP

97 Interleaving String 5 2 string Recursion

          DP

98 Validate Binary Search Tree 3 5 tree DFS

99 Recover Binary Search Tree 4 2 tree DFS

100 Same Tree 1 1 tree DFS

101 Symmetric Tree 1 2 tree DFS

102 Binary Tree Level Order Traversal 3 4 tree BFS

103 Binary Tree Zigzag Level Order Traversal 4 3 queue BFS

        tree Stack

104 Maximum Depth of Binary Tree 1 1 tree DFS

105 Construct Binary Tree from Preorder and Inorder Tr 3 3 array DFS

        tree  

106 Construct Binary Tree from Inorder and Postorder T 3 3 array DFS

        tree  

107 Binary Tree Level Order Traversal II 3 1 tree BFS

108 Convert Sorted Array to Binary Search Tree 2 3 tree DFS

109 Convert Sorted List to Binary Search Tree 4 3 linked list Recursion

          Two Pointers

110 Balanced Binary Tree 1 2 tree DFS

111 Minimum Depth of Binary Tree 1 1 tree DFS

112 Path Sum 1 3 tree DFS

113 Path Sum II 2 2 tree DFS

114 Flatten Binary Tree to Linked List 3 3 tree Recursion

          Stack

115 Distinct Subsequences 4 2 string DP

116 Populating Next Right Pointers in Each Node 3 3 tree DFS

117 Populating Next Right Pointers in Each Node II 4 2 tree DFS

118 Pascal's Triangle 2 1 array  

119 Pascal's Triangle II 2 1 array  

120 Triangle 3 1 array DP

121 Best Time to Buy and Sell Stock 2 1 array DP

122 Best Time to Buy and Sell Stock II 3 1 array greedy

123 Best Time to Buy and Sell Stock III 4 1 array DP

124 Binary Tree Maximum Path Sum 4 2 tree DFS

125 Valid Palindrome 2 5 string Two Pointers

126 Word Ladder II 1 1    

127 Word Ladder 3 5 graph BFS

          shortest path

128 Longest Consecutive Sequence 4 3 array  

129 Sum Root to Leaf Numbers 2 4 tree DFS

130 Surrounded Regions 4 3 array BFS

          DFS

131 Palindrome Partitioning 3 4 string DFS

132 Palindrome Partitioning II 4 3 string DP

Dynamic Programming

Edit Distance Maximum Subarray Minimum Path Sum Unique Paths Unique Paths II Longest Palindromic Substring Interleaving String Triangle Distinct Subsequences Decode Ways Palindrome Partitioning II Maximal Rectangle

Recursion

N-Queens N-Queens II Balanced Binary Tree Binary Tree Inorder Traversal Binary Tree Maximum Path Sum Convert Sorted Array to Binary Search Tree Convert Sorted List to Binary Search Tree Flatten Binary Tree to Linked List Maximum Depth of Binary Tree Minimum Depth of Binary Tree Path Sum Permutations Permutations II Populating Next Right Pointers in Each Node Pow(x, n) Same Tree Subsets Sum Root to Leaf Numbers Swap Nodes in Pairs Symmetric Tree Valid Palindrome Validate Binary Search Tree Restore IP Addresses Combinations Interleaving String (dp is the best) Combination Sum II Letter Combinations of a Phone Numbers Word Search Construct Binary Tree from Inorder and Postorder Traversal Construct Binary Tree from Preorder and Inorder Traversal Generate Parentheses Surrounded Regions (runtime error) Palindrome Partitioning Combination Sum Sudoku Solver Unique Binary Search Trees II

Binary Search

Search Insert Position Search a 2D Matrix Search for a Range Search in Rotated Sorted Array Sqrt(x)

Sequence

Container With Most Water Count and Say First Missing Positive Implement strStr() Jump Game Jump Game II Length of Last Word Longest Common Prefix Longest Substring Without Repeating Characters Merge Sorted Array Palindrome Number Plus One Remove Duplicates from Sorted Array Remove Duplicates from Sorted Array II Remove Element Reverse Integer Search in Rotated Sorted Array II Sort Colors Two Sum 3Sum 3Sum Closest 4Sum Add Binary Longest Palindromic Substring Next Permutation Longest Valid Parentheses Climbing Stairs Permutation Sequence Simplify Path String to Integer (atoi) Minimum Window Substring Longest Consecutive Sequence Trapping Rain Water Valid Number

Linked List

Add Two Numbers Convert Sorted List to Binary Search Tree Merge Two Sorted Lists Partition List Remove Duplicates from Sorted List Remove Duplicates from Sorted List II Remove Nth Node From End of List Reverse Linked List II Reverse Nodes in k-Group Rotate List Swap Nodes in Pairs

Stack

Binary Tree Inorder Traversal Binary Tree Level Order Traversal II Valid Parentheses

Queue

Binary Tree Level Order Traversal Binary Tree Level Order Traversal II Populating Next Right Pointers in Each Node II Symmetric Tree Surrounded Regions Word Ladder

Tree

Balanced Binary Tree Binary Tree Inorder Traversal Binary Tree Level Order Traversal Binary Tree Level Order Traversal II Binary Tree Maximum Path Sum Convert Sorted Array to Binary Search Tree Convert Sorted List to Binary Search Tree Flatten Binary Tree to Linked List Maximum Depth of Binary Tree Minimum Depth of Binary Tree Path Sum Same Tree Sum Root to Leaf Numbers Symmetric Tree Validate Binary Search Tree

from http://blog.csdn.net/doc_sgl/article/details/11664539

[Question] Insert Plus and Minus to Complete Expression

Question

link

Given a string of numbers, eg. “43868643”. Put ‘+’ and ‘-’ in between, and build an expression.

Solution

Iterate thru the input string and do DFS recrusively.

At each position, there’s 3 possibilities: plus, minus or do not skip.

Code

public List<String> solve(String str) {
    if (str == null || str.length() == 0) {
        return null;
    }
    List<String> result = new ArrayList<String>();
    helper(result, "", 0, str);
    Collections.sort(result);
    return result;
}

private void helper(List<String> result, String curExp, int curVal, String remain) {
    if (curVal == Integer.parseInt(remain)) {
        result.add(curExp + "=" + remain);
    } else if (curVal + Integer.parseInt(remain) == 0) {
        result.add(curExp + "=-" + remain);
    }
    for (int i = 1; i < remain.length(); i++) {
        String nextStr = remain.substring(0, i);
        int nextNum = Integer.parseInt(nextStr);

        // case 1: add a + between curExp and nextStr
        String newExp = curExp + "+" + nextStr;
        int newVal = curVal + nextNum;
        helper(result, newExp, newVal, remain.substring(i));

        // case 2: '-' sign
        newExp = curExp + "-" + nextStr;
        newVal = curVal - nextNum;
        helper(result, newExp, newVal, remain.substring(i));
    }
}

Testing

Input is 4312
Print the list: 
+4-3+1=2
-4+3-1=-2

Input is 43868643
Print the list: 
+4+3+8+6-8-6-4=3
+4+3+8-6-8+6-4=3
+4+3+86-86-4=3
+4+3-8+6+8-6-4=3
+4+3-8+68-64=3
+4+3-8-6+8+6-4=3
+4+3-86+86-4=3
+4-3+8+6-8-6-4=-3
+4-3+8-6-8+6-4=-3
+4-3+86-86-4=-3
+4-3-8+6+8-6-4=-3
+4-3-8+68-64=-3
+4-3-8-6+8+6-4=-3
+4-3-86+86-4=-3
+43+8+6-8-6=43
+43+8-6-8+6=43
+43+86-86=43
+43-8+6+8-6=43
+43-8-6+8+6=43
+43-86+86=43
-4+3+8+6-8-6+4=3
-4+3+8-6-8+6+4=3
-4+3+8-68+64=3
-4+3+86-86+4=3
-4+3-8+6+8-6+4=3
-4+3-8-6+8+6+4=3
-4+3-86+86+4=3
-4-3+8+6-8-6+4=-3
-4-3+8-6-8+6+4=-3
-4-3+8-68+64=-3
-4-3+86-86+4=-3
-4-3-8+6+8-6+4=-3
-4-3-8-6+8+6+4=-3
-4-3-86+86+4=-3
-43+8+6-8-6=-43
-43+8-6-8+6=-43
-43+86-86=-43
-43-8+6+8-6=-43
-43-8-6+8+6=-43
-43-86+86=-43

[Question] Get Max Number Game (Minmax + Dp)

Question

link

两个人(A,B)参与一个游戏,规则如下:

1)一个随机的整数数列有偶数个数,a1,a2,…a2n

2)A 先从数列取数,但只能从两头取,a1 or a2n

3)然后B取数,也是只能从剩下的两头取,依此类推,两个人轮流,都只能从两头取

Output the max sum of numbers that player 1 is going to get.

Solution

This question can be solved with DP by using the following 3 equations:

  1. sum[i][j] sum of number from i to j
  2. val[i][j]: the max value that can be obtained if only the range [i,j] is left and you take the move first
  3. pos[][] is related to val[][], as it denotes whether we take i or j

After we got sum[][] array fully filled up, the transition equation of val[][] looks like:

val[x][y] = sum[x][y] - MIN( val[x+1][y], val[x][y-1] )

As for pos[][]:

pos[x][y] = x  if val[x+1][y] < val[x][y-1]
            y  otherwise

Code

public int getMaxSumPlayerOne(int[] input) {
    int len = input.length;
    // sum[i][j] sum of number from i to j
    int[][] sum = new int[len][len];
    // val[i][j]: the max value that can be obtained if only
    // the range [i,j] is left and you take the move first
    int[][] val = new int[len][len];
    // pos is related to val, as it denotes whether we take i or j
    int[][] pos = new int[len][len];

    // 1. fill in sum[][]
    for (int x = 0; x < len; x++) {
        for (int y = x; y < len; y++) {
            if (x == y) {
                sum[x][y] = input[x];
            } else if (x == 0) {
                // fill up the first row in the sum[][] dp array
                sum[x][y] = sum[x][y - 1] + input[y];
            } else {
                // starting from the 2nd row, it's gonna make use of 1st row
                // x >= 1
                sum[x][y] = sum[0][y] - sum[0][x - 1];
            }
        }
    }

    // 2. fill in val[][] and pos[][]
    for (int x = len - 1; x >= 0; x--) {
        for (int y = x; y < len; y++) {
            if (x == y) {
                val[x][y] = input[x];
                pos[x][y] = x;
            } else {
                // when I choose either x or y, I look at what the opponent
                // is gonna get after my move, then chose the smaller
                // v[][] for the remaining part
                val[x][y] = sum[x][y] - Math.min(val[x + 1][y], val[x][y - 1]);
                pos[x][y] = val[x + 1][y] < val[x][y - 1] ? x : y;
            }
        }
    }
    this.printSteps(pos, len);
    return val[0][len - 1];
}

Testing

Input {1, 4, 3, 2}
Player 1 take position 3
Player 2 take position 2
Player 1 take position 1
Player 2 take position 0
max sum for player 1 is 6

Input {7, 5, 2, 6, 9, 8, 3, 4}
Player 1 take position 0
Player 2 take position 1
Player 1 take position 7
Player 2 take position 6
Player 1 take position 5
Player 2 take position 4
Player 1 take position 3
Player 2 take position 2
max sum for player 1 is 25

[Amazon] Infix to Postfix Conversion

Question

link, link.

example: A * B + C becomes A B * C +

A * (B + C) becomes A B C + *

Solution

One of the main purpose of converting infix to postfix is to remove alll parentheses from the expression.

This is a very difficult question. The solution is:

  1. Print operands as they arrive.

  2. If the incoming symbol is ‘+’ or ‘-’ or ‘(’, push it on the stack.

  3. If the incoming symbol is a ‘)’, pop the stack and print the operators until you see a ‘(’. Discard the pair of parentheses.

  4. If the incoming symbol is ‘*’ or ‘/’, pop until we sees ‘+’ or ‘-’ or ‘(’ at top of the stack, then push the symbol onto the stack.

  5. At the end of the expression, pop and print all operators on the stack. (No parentheses should remain.)

Code

public String solve(String infix) {
    StringBuilder sb = new StringBuilder();
    // get next operand or non-operand
    // notice that operand is >=1 chars
    int p = 0;
    int len = infix.length();
    Stack<Character> stack = new Stack<Character>();

    while (p != len) {
        if (isDigit(infix.charAt(p))) {
            // if char at p is a digit
            int q = p;
            while (q != len && isDigit(infix.charAt(q))) {
                q++;
            }
            // it is a number in the range [p, q-1]
            sb.append(infix.substring(p, q) + " ");
            p = q;
        } else {
            // if char at p is + - * / or ( )
            char op = infix.charAt(p++);
            if (op == ')') {
                // pop until sees a '('
                while (stack.peek() != '(') {
                    sb.append(stack.pop() + " ");
                }
                stack.pop();
            } else if (op == '(' || op == '+' || op == '-') {
                stack.push(op);
            } else {
                // if * or /
                // pop until sees + or - or '('
                while (!stack.isEmpty()) {
                    if (stack.peek() == '+' || stack.peek() == '-' || stack.peek() == '(') {
                        break;
                    }
                    sb.append(stack.pop() + " ");
                }
                stack.push(op);
            }
        }
    }
    // reach Eof, pop everything
    while (!stack.isEmpty()) {
        sb.append(stack.pop() + " ");
    }
    return sb.toString();
}

[Question] Shuffle and Get Max Difference

Question

link

Given an array with four integers A, B, C, D, shuffle them in some order (there are 24 shuffles).

… Get the best shuffle such that

F(S) = abs(s[0]-s[1]) + abs(s[1]-s[2])+ abs(s[2]-s[3]) is maximum

For example

A=5, B= 3, C=-1, D =5
s[0]=5, s[1]=-1, s[2]= 5, s[3] =3

will give F[s] =14 as max diff

Solution

Referring to this execellent answer:

  1. sort input and we get 4 number from min to max: A B C D
  2. swap A and B - B A C D
  3. swap C and D - B A D C
  4. swap head and tail - C A D B

Finally you got CADB or BDAC.

[Question] Count Arithmetic Slices

Question

Given an unsorted array of length N, a slice is defined as a pair of numbers (P, Q) so that:

  1. 0 <= P < Q <= N
  2. A[P], A[P+1]….A[Q] is arithmetic sequence

Example:

input = { -1, 1, 3, 3, 3, 2, 1, 0 }

Output 5 because there’re slices:

(0, 2) (2, 4) (4, 6) (4, 7) (5, 7)

Solution

  1. count the length of arithmetic (countinuous) sequence
  2. form some slices
  3. proceed from the end of that sequence, till the end.

Code

public int solve(int[] input) {
    int len = input.length;
    int p = 0;
    int totalSlices = 0;

    while (p + 1 < len) {
        // check if there is a arithmetic sequence starting at p
        // note that p is NOT the last element.
        int diff = input[p + 1] - input[p];
        int q = p + 1;

        // starting from q, check arithmetic difference
        while (q < len) {
            if (input[q] - input[q - 1] == diff) {
                q++;
            } else {
                break;
            }
        }

        // so, the range [p, q-1] is a arithmetic sequence.
        int seqLength = q - p;
        if (seqLength >= 3) {
            totalSlices += getSlicesCountFromArithmeticSeq(seqLength);
        }

        // update p (skip the range [p, q-1])
        p = q - 1;
    }
    return totalSlices;
}

private int getSlicesCountFromArithmeticSeq(int k) {
    // choose 2 from (k - 1)
    return (k - 1) * (k - 2) / 2;
}

[Question] Number of Bus Stations (Meeting Rooms)

Question

link

At a bus-station, you have time-table for buses arrival and departure. You need to find the minimum number of platforms so that all the buses can be accommodated as per their schedule.

Example: Time table is like below:

Bus         Arrival         Departure 
BusA        0900 hrs        0930 hrs
BusB        0915 hrs        1300 hrs
BusC        1030 hrs        1100 hrs
BusD        1045 hrs        1145 hrs

The answer must be 3.

This question can also be in other forms:

Given a vector of Nodes, each of which contain the start and end time of a meeting, find the maximum number of rooms one would have to book for the day.

Solution

The answer is same as finding the maximum number of bus at the bus-station at the same time.

The suggestted solution from here:

So first sort all the arrival(A) and departure(D) time in an int array. Please save the corresponding arrival or departure in the array also.

After sorting our array will look like this:

0900    0915    1930    1030    1045    1100    1145    1300
A       A       D       A       A       D       D       D

Now use a counter. When sees an A, increment. When sees an D, decreament. In the end, return the largest counter value.

Note: If you have a arriving and a departing at same time, put departure time first.

code

public int solve(List<Meeting> input) {
    List<Event> events = new ArrayList<Event>();
    for (Meeting i : input) {
        events.add(new Event(i.start, 1));
        events.add(new Event(i.end, -1));
    }
    Collections.sort(events);

    int currentNeeds = 0;
    int maxNeeds = 0;
    for (Event e : events) {
        currentNeeds += e.diff;
        maxNeeds = Math.max(maxNeeds, currentNeeds);
    }
    return maxNeeds;
}

supporting classes:

class Event implements Comparable<Event> {
    int time;
    int diff;
    // variable diff have value of 1 or -1
    // when = 1, it means starting a meeting and 1 more room needed
    // when = -1, it means ending a meeting and 1 less room needed

    public Event(int a, int b) {
        time = a;
        diff = b;
    }

    @Override
    public int compareTo(Event o) {
        if (this.time == o.time) {
            return this.diff - o.diff;
        }
        return this.time - o.time;
    }
}

class Meeting {
    int start;
    int end;

    public Meeting(int a, int b) {
        start = a;
        end = b;
    }
}