Wednesday, May 12, 2021

LeetCode [1539] Kth Missing Positive Number

 1539. Kth Missing Positive Number

Easy

Given an array arr of positive integers sorted in a strictly increasing order, and an integer k.

Find the kth positive integer that is missing from this array.

 

Example 1:

Input: arr = [2,3,4,7,11], k = 5
Output: 9
Explanation: The missing positive integers are [1,5,6,8,9,10,12,13,...]. The 5th missing positive integer is 9.

Example 2:

Input: arr = [1,2,3,4], k = 2
Output: 6
Explanation: The missing positive integers are [5,6,7,...]. The 2nd missing positive integer is 6.

 

Constraints:

  • 1 <= arr.length <= 1000
  • 1 <= arr[i] <= 1000
  • 1 <= k <= 1000
  • arr[i] < arr[j] for 1 <= i < j <= arr.length
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Solution {

    public int findKthPositive(int[] arr, int k) {
        int n = arr.length;
        //arr[i-1] - i = missed
        //find max i s.t. arr[i-1] - i < k
        //return i+k
        int l = 0, r = n, mid = 0;
        while(l<=r){
            mid = (l+r)/2;
            int missed = getMissed(arr, mid);
            if(missed<k && (mid==r || getMissed(arr, mid+1) >= k)) break;
            else if(missed<k) l = mid+1;
            else r = mid-1;
        }
        return mid+k;
    }
    
    int getMissed(int[] arr, int len){
        if(len==0) return 0;
        else return arr[len-1] - len;
    }
}

Sunday, May 9, 2021

LeetCode [1650] Lowest Common Ancestor of a Binary Tree III

 1650. Lowest Common Ancestor of a Binary Tree III

Medium

Given two nodes of a binary tree p and q, return their lowest common ancestor (LCA).

Each node will have a reference to its parent node. The definition for Node is below:

class Node {
    public int val;
    public Node left;
    public Node right;
    public Node parent;
}

According to the definition of LCA on Wikipedia: "The lowest common ancestor of two nodes p and q in a tree T is the lowest node that has both p and q as descendants (where we allow a node to be a descendant of itself)."

 

Example 1:

Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
Output: 3
Explanation: The LCA of nodes 5 and 1 is 3.

Example 2:

Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4
Output: 5
Explanation: The LCA of nodes 5 and 4 is 5 since a node can be a descendant of itself according to the LCA definition.

Example 3:

Input: root = [1,2], p = 1, q = 2
Output: 1

 

Constraints:

  • The number of nodes in the tree is in the range [2, 105].
  • -109 <= Node.val <= 109
  • All Node.val are unique.
  • p != q
  • p and q exist in the tree.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/*
// Definition for a Node.
class Node {
    public int val;
    public Node left;
    public Node right;
    public Node parent;
};
*/

class Solution {
    public Node lowestCommonAncestor(Node p, Node q) {
        Node root  = p;
        while(root.parent!=null) root = root.parent;
        return helper(root, p, q);
    }
    
    Node helper(Node node, Node p, Node q){
        if(node==null) return null;
        if(node.val == p.val || node.val == q.val) return node;
        Node l = helper(node.left, p, q);
        Node r = helper(node.right, p, q);
        if(l!=null && r!=null) return node;
        if(l!=null) return l;
        return r;
    }
}

Saturday, May 8, 2021

LeetCode[1762] Buildings With an Ocean View

1762. Buildings With an Ocean View
Medium

There are n buildings in a line. You are given an integer array heights of size n that represents the heights of the buildings in the line.

The ocean is to the right of the buildings. A building has an ocean view if the building can see the ocean without obstructions. Formally, a building has an ocean view if all the buildings to its right have a smaller height.

Return a list of indices (0-indexed) of buildings that have an ocean view, sorted in increasing order.

 

Example 1:

Input: heights = [4,2,3,1]
Output: [0,2,3]
Explanation: Building 1 (0-indexed) does not have an ocean view because building 2 is taller.

Example 2:

Input: heights = [4,3,2,1]
Output: [0,1,2,3]
Explanation: All the buildings have an ocean view.

Example 3:

Input: heights = [1,3,2,4]
Output: [3]
Explanation: Only building 3 has an ocean view.

Example 4:

Input: heights = [2,2,2,2]
Output: [3]
Explanation: Buildings cannot see the ocean if there are buildings of the same height to its right.

 

Constraints:

  • 1 <= heights.length <= 105
  • 1 <= heights[i] <= 109

 


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
class Solution {
    public int[] findBuildings(int[] heights) {
        List<Integer> list = new ArrayList<>();
        int n = heights.length;
        
        int tall = 0;
        for(int i = n-1; i>=0; --i){
            if(heights[i]>tall){
                list.add(0, i);
                tall = Math.max(tall, heights[i]);
            }
        }
        
        int[] ret = new int[list.size()];
        for(int i=0; i<list.size(); ++i) ret[i] = list.get(i);
        return ret;
    }
}

Thursday, April 29, 2021

LeetCode [1460] Make Two Arrays Equal by Reversing Sub-arrays

 1460. Make Two Arrays Equal by Reversing Sub-arrays

Easy

Given two integer arrays of equal length target and arr.

In one step, you can select any non-empty sub-array of arr and reverse it. You are allowed to make any number of steps.

Return True if you can make arr equal to target, or False otherwise.

 

Example 1:

Input: target = [1,2,3,4], arr = [2,4,1,3]
Output: true
Explanation: You can follow the next steps to convert arr to target:
1- Reverse sub-array [2,4,1], arr becomes [1,4,2,3]
2- Reverse sub-array [4,2], arr becomes [1,2,4,3]
3- Reverse sub-array [4,3], arr becomes [1,2,3,4]
There are multiple ways to convert arr to target, this is not the only way to do so.

Example 2:

Input: target = [7], arr = [7]
Output: true
Explanation: arr is equal to target without any reverses.

Example 3:

Input: target = [1,12], arr = [12,1]
Output: true

Example 4:

Input: target = [3,7,9], arr = [3,7,11]
Output: false
Explanation: arr doesn't have value 9 and it can never be converted to target.

Example 5:

Input: target = [1,1,1,1,1], arr = [1,1,1,1,1]
Output: true

 

Constraints:

  • target.length == arr.length
  • 1 <= target.length <= 1000
  • 1 <= target[i] <= 1000
  • 1 <= arr[i] <= 1000

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
class Solution {
    public boolean canBeEqual(int[] target, int[] arr) {
        Map<Integer, Integer> map = new HashMap<>();
        for(int i : target) map.put(i, map.getOrDefault(i, 0)+1);
        for(int i : arr) map.put(i, map.getOrDefault(i, 0)-1);
        for(int k : map.keySet()){
            if(map.get(k)!=0) return false;
        }
        return true;
    }
}

Wednesday, April 28, 2021

Shortest Cycle in a Directed Graph

https://stackoverflow.com/questions/3911626/find-cycle-of-shortest-length-in-a-directed-graph-with-positive-weights
 
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
package ShortestCycle;

import java.util.*;
public class Main {
    public static void main(String[] args) {
        System.out.println("Shortest Cycle");

        Map<Integer, List<Integer>> map = new HashMap<>();
        map.put(0, new ArrayList<>());
        map.put(1, new ArrayList<>());
        map.put(2, new ArrayList<>());
        map.put(3, new ArrayList<>());
        map.put(4, new ArrayList<>());

        map.get(0).add(1);
        map.get(0).add(2);
        map.get(1).add(3);
        map.get(2).add(4);
        map.get(3).add(0);
        map.get(4).add(3);

        List<Integer> prev = new ArrayList<>();
        prev.add(3);

        int[] dist = new int[5];
        Arrays.fill(dist, Integer.MAX_VALUE);
        //dist, index
        PriorityQueue<int[]> pq = new PriorityQueue<>((a,b) -> a[0]-b[0]);
        pq.add(new int[]{0, 0});
        while(!pq.isEmpty()){
            int[] top = pq.poll();
            int d = top[0], index = top[1];
            if(d<dist[index]){
                dist[index] = d;
                if(map.containsKey(index)){
                    for(int next : map.get(index)){
                        if(d+1 < dist[next]){
                            pq.add(new int[]{d+1, next});
                        }
                    }
                }
            }
        }

        int min = Integer.MAX_VALUE;
        for(int p : prev){
            min = Math.min(min, dist[p]);
        }
        System.out.println(min+1);
    }
}

Tuesday, April 27, 2021

SnakeAndLadder

Link 


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
package SnakeLadder;

import java.util.*;

public class Main {
    static int N;// number of cells
    static int[] moves;// end of snake or ladder

    public static void main(String[] args) {
        N = 30;
        moves = new int[N];
        Arrays.fill(moves, -1);
        // Ladders
        moves[2] = 21;
        moves[4] = 7;
        moves[10] = 25;
        moves[19] = 28;

        // Snakes
        moves[26] = 0;
        moves[20] = 8;
        moves[16] = 3;
        moves[18] = 6;

        int p = getMinPath();
        System.out.println(p);
    }

    static int getMinPath(){
        Queue<Integer> que = new LinkedList<>();
        Set<Integer> visited = new HashSet<>();
        que.add(0);
        visited.add(0);
        int path = 0;
        
        while(!que.isEmpty()){
            int sz = que.size();
            for(int i=0; i<sz; ++i){
                int cell = que.poll();
                if(cell==(N-1)) return path;

                for(int k=1; k<=6; ++k){
                    if(cell+k<N && !visited.contains(cell+k)){
                        que.add(cell+k);
                        visited.add(cell+k);

                        if(moves[cell+k]>=0){
                            que.add(moves[cell+k]);
                            visited.add(moves[cell+k]);
                        } 
                    }
                }
            }
            path++;
        }

        return path;
    }
}

Employee architecture


Link


题目大意应该是给雇主关系结构图, 是direct graph, 会给adjacent list, 好像允许有employee有>=1 boss。 一般首先会问这个关系是不是valid ?

我个人的理解valid是两个条件:

1. 所有的node都在一个群, 有一个root。

2. 不能有cycle。

 

因为题目允许有>=1 个boss, 所以indgree可以>=1。

 

我思路是两部:

1.所以node一个群, 把图当成indirect graph,然后union find, 看最后是不是所有都connected。

 

2.有向图 check cycle。

 

如果两步都通过,就说明是valid。

 

1. 地里最近常出现的雇主关系题 最开始就是dfs找有多少个员工 followup就是讨论一下各种可能出现的情况包括loop怎么判断

检查是树还是森林,使用dfs在无向graph上即可。

 

有无cycle,蠡口,儿凝器canFinish()最简单的是topological sort。

DFS无向图, 从任何一点出发, 走一边能全部visit并且不会遇到visited的node,就是tree吗?

 

不过这个题目,结构可能不是标准的tree, 因为可能允许一个node有多个parent。 这样用DFS可能不行。

 

恩, topological sorting查有向图cycle也可以。

orginization employee architecture, find eid score from repporting tree,  find loops and dual reporting in reporting tree.  应该属于简单题,就是层次多 。



 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
package EmploySystem;

import java.util.*;
public class Main {
    public static void main(String[] args) {
        Map<Character, List<Character>> map = new HashMap<>();
        map.put('A', new ArrayList<>());
        map.put('B', new ArrayList<>());
        map.put('C', new ArrayList<>());
        map.put('D', new ArrayList<>());
        map.put('E', new ArrayList<>());

        map.get('A').add('B');
        map.get('A').add('C');
        map.get('A').add('E');
        map.get('B').add('A');
        map.get('D').add('E');

        boolean valid = isValid(map);
        System.out.println("Valid: " + valid);
        if(valid){
            Set<Character> employees = getAllEmployees('A', map);
            System.out.println(employees.toString());
        }
    }

    static boolean hasCycle(Map<Character, List<Character>> map, 
                            Set<Character> visited,
                            Set<Character> path,
                            char employee){
        visited.add(employee);
        if(map.containsKey(employee)){
            for(char next : map.get(employee)){
                if(path.contains(next)) return true;
                if(!visited.contains(next)){
                    path.add(next);
                    if(hasCycle(map, visited, path, next)) return true;
                    path.remove(next);
                }
            }
        }
        return false;
    }

    static boolean isValid(Map<Character, List<Character>> map){
        Set<Character> visited = new HashSet<>();
        Set<Character> path = new HashSet<>();
        for(char employee : map.keySet()){
            path.add(employee);
            if(hasCycle(map, visited, path, employee)) return false;
            path.remove(employee);
        }
        return true;
    }

    static Set<Character> getAllEmployees(char employer, 
                                          Map<Character, List<Character>> map){
        Set<Character> employees = new HashSet<>();
        if(map.containsKey(employer)){
            for(char employee : map.get(employer)){
                employees.add(employee);
                employees.addAll(getAllEmployees(employee, map));
            }
        }
        return employees;
    }
}