1029. Two City Scheduling

There are 2N people a company is planning to interview. The cost of flying the i-th person to city A is costs[i][0], and the cost of flying the i-th person to city B is costs[i][1].

Return the minimum cost to fly every person to a city such that exactly Npeople arrive in each city.

 

Example 1:

Input:

[[10,20],[30,200],[400,50],[30,20]]

Output:

110

Explanation:

The first person goes to city A for a cost of 10.
The second person goes to city A for a cost of 30.
The third person goes to city B for a cost of 50.
The fourth person goes to city B for a cost of 20.

The total minimum cost is 10 + 30 + 50 + 20 = 110 to have half the people interviewing in each city.

 

Note:

  1. 1 <= costs.length <= 100
  2. It is guaranteed that costs.length is even.
  3. 1 <= costs[i][0], costs[i][1] <= 1000

 

class Solution {

    /**
     * @param Integer[][] $costs
     * @return Integer
     */
    function twoCitySchedCost($costs) {
        usort($costs, function($arr1, $arr2) {
            return (abs($arr1[1]-$arr1[0]) < abs($arr2[1]-$arr2[0]) ) ? 1 : -1;
        });

        $a = 0;
        $b = 0;
        $total = 0;
        foreach($costs as $c){
            if($c[0] < $c[1]){

                if($a < count($costs)/2){
                    $total += $c[0];
                    $a ++;
                } else {
                    $total += $c[1];
                    $b ++;
                }
               
            } else{
                if($b < count($costs)/2){
                    $total += $c[1];
                    $b ++;
                } else {
                    $total += $c[0];
                    $a ++;
                }
                
            } 
        } 

        return $total;
    }
}

16ms.

 

 

Thoughts:

  • This code was used for the contest, so it’s not well structured (in terms of redundancy)
  • The basic idea:
    • Sort by switching cost (price diff), DESC.
    • then for each person, assign to lower cost city until full.
      • in case of full, assign to city with higher cost
    • Since sorted by price diff, at the time one city is full,  the cost to switch remaining people to the second choice is the lowest

If I’m a interviewer:

  • Let’s try three cities….
  • What about the capacity of each city is specified?
  • And what about the capacity is flexible and within a range provided?

1021. Remove Outermost Parentheses

A valid parentheses string is either empty ("")"(" + A + ")", or A + B, where A and B are valid parentheses strings, and + represents string concatenation.  For example, """()""(())()", and "(()(()))" are all valid parentheses strings.

A valid parentheses string S is primitive if it is nonempty, and there does not exist a way to split it into S = A+B, with A and B nonempty valid parentheses strings.

Given a valid parentheses string S, consider its primitive decomposition: S = P_1 + P_2 + ... + P_k, where P_i are primitive valid parentheses strings.

Return S after removing the outermost parentheses of every primitive string in the primitive decomposition of S.

 

Example 1:

Input:

"(()())(())"

Output:

"()()()"

Explanation:

The input string is "(()())(())", with primitive decomposition "(()())" + "(())".
After removing outer parentheses of each part, this is "()()" + "()" = "()()()".

Example 2:

Input:

"(()())(())(()(()))"

Output:

"()()()()(())"

Explanation:

The input string is "(()())(())(()(()))", with primitive decomposition "(()())" + "(())" + "(()(()))".
After removing outer parentheses of each part, this is "()()" + "()" + "()(())" = "()()()()(())".

Example 3:

Input:

"()()"

Output:

""

Explanation:

The input string is "()()", with primitive decomposition "()" + "()".
After removing outer parentheses of each part, this is "" + "" = "".

 

Note:

  1. S.length <= 10000
  2. S[i] is "(" or ")"
  3. S is a valid parentheses string

class Solution {
    public String removeOuterParentheses(String S) {
        int lv = 0;
        String result = "";
        
        for(char c : S.toCharArray()){
            if(c == '('){
                if(lv > 0){
                    result += c;
                }
                lv ++;
                
            } else if(c == ')'){
                lv--;
                if(lv > 0){
                    result += c;
                }
            }
        }
        return result;
    }
}

 

* Using a StringBuilder will somehow improve the performance.

Thoughts:

Since we can assume the input is valid, just use a counter to mark the depth. Send char to result only when depth >= 1

If I’m a Interviewer

  1. What if the input string is not always valid?
    • ref: LC20
  2. What if we upgrade parentheses to brackets ()[]{} ?
    • Use Stack and Stack.size() instead of level counter
  3. What if we remove inner most (max depth) parentheses instead?
    • Go through twice, 1) find max depth, 2) copy to result and skip max depth.

Well we can always construct an array of ints (levels) as a form of representation.

For example, “(()())(())(()(()))” -> [1,2,2,1,2,1,2,2,3]

Then we can easily remove any levels (outer/inner/somewhere in the middle).

  • Remove Outer: remove 1, everything else —
  • Remove Inner: remove max
  • Remove Level2: remove 2, everything > 2 decrease by 1.

 


21. Merge Two Sorted Lists

Merge two sorted linked lists and return it as a new list. The new list should be made by splicing together the nodes of the first two lists.

Example:

Input: 1->2->4, 1->3->4
Output: 1->1->2->3->4->4

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        ListNode cur = new ListNode(0); // Put something to start
        ListNode result = cur;
        while(l1 != null || l2 != null){
            if(l1 == null){
                cur.next = new ListNode(l2.val);
                l2 = l2.next;
            } else if(l2 == null){
                cur.next = new ListNode(l1.val);
                l1 = l1.next;
            } else if(l1.val < l2.val){
                cur.next = new ListNode(l1.val);
                l1 = l1.next;
            } else {
                cur.next = new ListNode(l2.val);
                l2 = l2.next;
            }
            cur = cur.next;
        }
        return result.next; // Igonre the first node
    }
}

1 ms 37.1 MB

20. Valid Parentheses

Given a string containing just the characters '('')''{''}''[' and ']', determine if the input string is valid.

An input string is valid if:

  1. Open brackets must be closed by the same type of brackets.
  2. Open brackets must be closed in the correct order.

Note that an empty string is also considered valid.

Example 1:

Input:

 "()"

Output:

 true

Example 2:

Input:

 "()[]{}"

Output:

 true

Example 3:

Input:

 "(]"

Output:

 false

Example 4:

Input:

 "([)]"

Output:

 false

Example 5:

Input:

 "{[]}"

Output:

 true


class Solution {
    public boolean isValid(String s) {
        Stack<Character> stack = new Stack<>();
        for(char c : s.toCharArray()){
            switch(c){
                case '(':
                    stack.push(')');
                    break;
                case '[':
                    stack.push(']');
                    break;
                case '{':
                    stack.push('}');
                    break;
                default:
                    if(stack.isEmpty() || stack.peek() != c){
                        return false;
                    }
                    stack.pop();
                    
            }
        }
        return stack.isEmpty();
    }
}

 

14. Longest Common Prefix

Write a function to find the longest common prefix string amongst an array of strings.

If there is no common prefix, return an empty string "".

Example 1:

Input:

["flower","flow","flight"]

Output:

 "fl"

Example 2:

Input:

["dog","racecar","car"]

Output:

 ""

Explanation:

 There is no common prefix among the input strings.

Note:

All given inputs are in lowercase letters a-z.

 


class Solution {

    /**
     * @param String[] $strs
     * @return String
     */
    function longestCommonPrefix($strs) {
        if(empty($strs)){
            return "";
        }
        $result = "";
        for($i = 0; $i < strlen($strs[0]); $i ++){
            $cur = $strs[0][$i];
            foreach ($strs as $s){
                if($s[$i] != $cur){
                    return $result;
                }
            }
            $result.= $cur;
        }
        return $result;
        
    }
}

 

13. Roman to Integer

Roman numerals are represented by seven different symbols: IVXLCD and M.

Symbol


Value

I             1
V             5
X             10
L             50
C             100
D             500
M             1000

For example, two is written as II in Roman numeral, just two one’s added together. Twelve is written as, XII, which is simply X + II. The number twenty seven is written as XXVII, which is XX + V + II.

Roman numerals are usually written largest to smallest from left to right. However, the numeral for four is not IIII. Instead, the number four is written as IV. Because the one is before the five we subtract it making four. The same principle applies to the number nine, which is written as IX. There are six instances where subtraction is used:

  • I can be placed before V (5) and X (10) to make 4 and 9.
  • X can be placed before L (50) and C (100) to make 40 and 90.
  • C can be placed before D (500) and M (1000) to make 400 and 900.

Given a roman numeral, convert it to an integer. Input is guaranteed to be within the range from 1 to 3999.

Example 1:

Input:

 "III"

Output:

 3

Example 2:

Input:

 "IV"

Output:

 4

Example 3:

Input:

 "IX"

Output:

 9

Example 4:

Input:

 "LVIII"

Output:

 58

Explanation:

 L = 50, V= 5, III = 3.

Example 5:

Input:

 "MCMXCIV"

Output:

 1994

Explanation:

 M = 1000, CM = 900, XC = 90 and IV = 4.

class Solution {

    /**
     * @param String $s
     * @return Integer
     */
    function romanToInt($s) {
        $i= 0;
        $p = ["I"=>1, "V"=>5, "X"=>10, "L"=>50, "C"=> 100, "D"=>500, "M"=>1000];
        $result = 0;
        $increment = INF;
        while($i < strlen($s)){
            $new_increment =  $p[$s[$i]];
            if($increment < $new_increment){
                $result -= (2 * $increment);
            }
            $increment = $new_increment;
            $result += $increment;
            $i ++;
        }
        return $result;
    }
}

The solution is based on the fact that the input is valid, otherwise won’t work

1020. Partition Array Into Three Parts With Equal Sum

Given an array A of integers, return true if and only if we can partition the array into three non-empty parts with equal sums.

Formally, we can partition the array if we can find indexes i+1 < j with (A[0] + A[1] + ... + A[i] == A[i+1] + A[i+2] + ... + A[j-1] == A[j] + A[j-1] + ... + A[A.length - 1])

 

Example 1:

Input:

[0,2,1,-6,6,-7,9,1,2,0,1]

Output:

true
Explanation: 0 + 2 + 1 = -6 + 6 - 7 + 9 + 1 = 2 + 0 + 1

Example 2:

Input:

[0,2,1,-6,6,7,9,-1,2,0,1]

Output:

false

Example 3:

Input:

[3,3,6,5,-2,2,5,1,-9,4]

Output:

true
Explanation: 3 + 3 = 6 = 5 - 2 + 2 + 5 + 1 - 9 + 4

 

Note:

  1. 3 <= A.length <= 50000
  2. -10000 <= A[i] <= 10000
class Solution {

    /**
     * @param Integer[] $A
     * @return Boolean
     */
    function canThreePartsEqualSum($A) {
        $mean = array_sum($A) / 3;
        if (floor($mean) != $mean){
            return false;
        }
        
        $count  = 0;
        $sum = 0;
        $i = 0;
        while ($i < count($A)){    
            $sum += $A[$i];
            $i ++;
            if($sum == $mean){
                $count ++;
                $sum = 0;
            }
        }
        return $count == 3;
    }
}

 

181. Employees Earning More Than Their Managers

The Employee table holds all employees including their managers. Every employee has an Id, and there is also a column for the manager Id.
+----+-------+--------+-----------+
| Id | Name  | Salary | ManagerId |
+----+-------+--------+-----------+
| 1  | Joe   | 70000  | 3         |
| 2  | Henry | 80000  | 4         |
| 3  | Sam   | 60000  | NULL      |
| 4  | Max   | 90000  | NULL      |
+----+-------+--------+-----------+

Given the Employee table, write a SQL query that finds out employees who earn more than their managers. For the above table, Joe is the only employee who earns more than his manager.

+----------+
| Employee |
+----------+
| Joe      |
+----------+

Thoughts:

Self  Join, nothing special


# Write your MySQL query statement below
SELECT e1.Name as Employee FROM Employee e1  LEFT JOIN Employee e2 on e2.id =  e1.ManagerId WHERE e2.Salary < e1.Salary;