Tuesday, May 31, 2022

598 · Zombie in Matrix [LintCode]

一刷 05/2022

 Version #1 BFS

Time O(MN)

Spance O(MN)

361 mstime cost

·

22.63 MBmemory cost

·

Your submission beats16.20 %Submissions

public class Solution {

/**
* @param grid: a 2D integer grid
* @return: an integer
*/
private static int WALL = 2;
private static int ZOMBIE = 1;
private static int HUMAN = 0;
private int[] dx = new int[]{1, 0, -1, 0};
private int[] dy = new int[]{0, -1, 0, 1};
public int zombie(int[][] grid) {
if (grid == null || grid.length == 0 || grid[0] == null || grid[0].length == 0) {
return 0;
}
int rows = grid.length, cols = grid[0].length;
Queue<int[]> que = new ArrayDeque<>();
boolean[][] visited = new boolean[rows][cols];
int humanCnt = 0;
for (int y = 0; y < rows; y++) {
for (int x = 0; x < cols; x++) {
if (grid[y][x] == HUMAN) {
humanCnt++;
}
if (grid[y][x] == ZOMBIE) {
visited[y][x] = true;
que.offer(new int[]{x, y});
}
}
}
int days = 0;
while (!que.isEmpty()) {
int size = que.size();
days++;
while (size-- > 0) {
int[] curr = que.poll();
for (int i = 0; i < 4; i++) {
int nx = curr[0] + dx[i];
int ny = curr[1] + dy[i];
if (nx < 0 || nx >= cols || ny < 0 || ny >= rows) {
continue;
}
if (visited[ny][nx] || grid[ny][nx] == WALL) {
continue;
}
if (grid[ny][nx] == HUMAN) {
humanCnt--;
}
visited[ny][nx] = true;
que.offer(new int[]{nx, ny});
}
}
if (humanCnt == 0) {
return days;
}
}
return -1;
}

618 · Search Graph Nodes [LintCode]

2649 mstime cost

·

22.94 MBmemory cost

·

Your submission beats11.00 %Submissions


 /**

* Definition for graph node.
* class UndirectedGraphNode {
* int label;
* ArrayList<UndirectedGraphNode> neighbors;
* UndirectedGraphNode(int x) {
* label = x; neighbors = new ArrayList<UndirectedGraphNode>();
* }
* };
*/


public class Solution {
/*
* @param graph: a list of Undirected graph node
* @param values: a hash mapping, <UndirectedGraphNode, (int)value>
* @param node: an Undirected graph node
* @param target: An integer
* @return: a node
*/
public UndirectedGraphNode searchNode(ArrayList<UndirectedGraphNode> graph,
Map<UndirectedGraphNode, Integer> values,
UndirectedGraphNode node,
int target) {
// write your code here
Queue<UndirectedGraphNode> que = new ArrayDeque<>();
Set<UndirectedGraphNode> visited = new HashSet<>();
que.offer(node);
visited.add(node);
if (values.containsKey(node) && values.get(node) == target) {
return node;
}
while (!que.isEmpty()) {
UndirectedGraphNode curr = que.poll();
for (UndirectedGraphNode next : curr.neighbors) {
if (visited.contains(next)) {
continue;
}
if (values.containsKey(next) && values.get(next) == target) {
return next;
}
visited.add(next);
que.offer(next);
}
}
return null;
}
}

1462. Course Schedule IV

 一刷 05/2022

Version #1 Topological Sort


Time O(E + V)

Space O(E + V)

Runtime: 124 ms, faster than 26.97% of Java online submissions for Course Schedule IV.
Memory Usage: 70.2 MB, less than 58.24% of Java online submissions for Course Schedule IV.

class Solution {

    public List<Boolean> checkIfPrerequisite(int numCourses, int[][] prerequisites, int[][] queries) {

        Set<Integer>[] graph = new HashSet[numCourses];

        int[] indegree = new int[numCourses];

        Set<Integer>[] preReq = new HashSet[numCourses];

        for (int i = 0; i < numCourses; i++) {

            graph[i] = new HashSet<>();

            preReq[i] = new HashSet<>();

        }

        for (int[] prerequisite : prerequisites) {

            int from = prerequisite[0];

            int to = prerequisite[1];

            graph[from].add(to);

            indegree[to]++;

        }

        Queue<Integer> que = new ArrayDeque<>();

        for (int i = 0; i < numCourses; i++) {

            if (indegree[i] == 0) {

                que.offer(i);

            }

        }

        

        while (!que.isEmpty()) {

            Integer curr = que.poll();

            for (int next : graph[curr]) {

                preReq[next].add(curr);

                preReq[next].addAll(preReq[curr]);

                indegree[next]--;

                if (indegree[next] == 0) {

                    que.offer(next);

                }

            }

        }

        List<Boolean> result = new ArrayList<>();

        for (int[] query : queries) {

            if (preReq[query[1]].contains(query[0])) {

                result.add(true);

            } else {

                result.add(false);

            }

        }

        return result;

    }

}

Monday, May 30, 2022

444. Sequence Reconstruction

 一刷 05/2022

Version #1 Topological Sort

Time O(#nums)

Space O(#nums^2)


class Solution {

    public boolean sequenceReconstruction(int[] nums, List<List<Integer>> sequences) {

        Map<Integer, Set<Integer>> graph = new HashMap<>();

        Map<Integer, Integer> indegree = new HashMap<>();

        for (int num : nums) {

            graph.put(num, new HashSet<>());

            indegree.put(num, 0);

        }

        for (List<Integer> sequence : sequences) {

            Integer from = null, to = null;

            for (Integer n : sequence) {

                if (from == null) {

                    from = n;

                    continue;

                }

                to = n;

                Set<Integer> neighbors = graph.get(from);

                if (!neighbors.contains(to)) {

                    neighbors.add(to);

                    indegree.put(to, indegree.get(to) + 1);

                }

                from = n;

            }

        }

        // for (Map.Entry<Integer, Set<Integer>> entry : graph.entrySet()) {

        //     System.out.printf("key-%d, set-%s\n", entry.getKey(), entry.getValue());

        // }

        Queue<Integer> que = new ArrayDeque<>();

        for (Map.Entry<Integer,Integer> entry : indegree.entrySet()) {

            if (entry.getValue() == 0) {

                que.offer(entry.getKey());

            }

        }

        int index = 0;

        while (!que.isEmpty()) {

            if (que.size() > 1) {

                return false;

            }

            Integer curr = que.poll();

            // System.out.println(curr);

            if (curr != nums[index++]) {

                return false;

            }

            for (Integer neighbor : graph.get(curr)) {

                int id = indegree.get(neighbor);

                id -= 1;

                if (id == 0) {

                    que.offer(neighbor);

                }

                indegree.put(neighbor, id);

            }

        }

        return true;

    }

}

Wednesday, May 25, 2022

1197. Minimum Knight Moves

 一刷

Version #1 BFS

TLE if we use HashMap to implement the visited grids

We should use a boolean array instead

Given the coordinate of the target as (x, y), the number of cells covered by the circle that is centered at point (0, 0) and reaches the target point is roughly \big(\max(|x|, |y|)\big) ^ 2

Time O(max(|x|, |y|)^2)

Space O(max(|x|, |y|)^2)

Runtime: 279 ms, faster than 60.99% of Java online submissions for Minimum Knight Moves.
Memory Usage: 91.8 MB, less than 54.57% of Java online submissions for Minimum Knight Moves.

class Solution {

    private int[] dx = new int[]{2, 1, -1, -2, -2, -1, 1, 2};

    private int[] dy = new int[]{1, 2, 2, 1, -1, -2, -2, -1};

    public int minKnightMoves(int x, int y) {

        if (x == 0 && y == 0) {

            return 0;

        }

        Queue<int[]> que = new ArrayDeque<>();

        boolean[][] visited = new boolean[601][601];

        que.offer(new int[]{0, 0});

        visited[300][300] = true;

        int step = 0;

        while (!que.isEmpty()) {

            int size = que.size();

            step++;

            while (size-- > 0) {

                int[] curr = que.poll();

                // y = curr[0], x = curr[1]

                for (int i = 0; i < 8; i++) {

                    int ny = curr[0] + dy[i];

                    int nx = curr[1] + dx[i];

                    if (nx == x && ny == y) {

                        return step;

                    }

                    if (visited[ny + 300][nx + 300]) {

                        continue;

                    }

                    que.offer(new int[]{ny, nx});

                    visited[ny + 300][nx + 300] = true;

                }

            }

        }

        return -1;

    }

}


Version #2 Bidirectional BFS

这里只是记录这种bidirectional的思路

实际写的时候visited array的boundary和offsite都非常tricky, 写错了好几次

如果不用visited array而用hash成string的方法就会TLE

所以问题很多

Time 和 Space complexity都和上面是一样的

Runtime: 207 ms, faster than 68.90% of Java online submissions for Minimum Knight Moves.
Memory Usage: 74.4 MB, less than 56.56% of Java online submissions for Minimum Knight Moves.


class Solution {

    private int[] dx = new int[]{2, 1, -1, -2, -2, -1, 1, 2};

    private int[] dy = new int[]{1, 2, 2, 1, -1, -2, -2, -1};

    

    private String hash(int[] grid) {

        return grid[0] + "," + grid[1];

    }

    

    private int offsite = 600;

    public int minKnightMoves(int x, int y) {

        if (x == 0 && y == 0) {

            return 0;

        }

        // Bidirectional BFS

        // Search from both start point and the end point

        int bound = 1201;

        int[][] sourceVisited = new int[bound][bound];

        int[][] targetVisited = new int[bound][bound];

        for (int i = 0; i < bound; i++) {

            for (int j = 0; j < bound; j++) {

                sourceVisited[i][j] = -1;

                targetVisited[i][j] = -1;

            }

        }

        

        Queue<int[]> sourceQue = new ArrayDeque<>();

        sourceVisited[offsite][offsite] = 0;

        sourceQue.offer(new int[]{0, 0});

        

        Queue<int[]> targetQue = new ArrayDeque<>();

        targetVisited[x + offsite][y + offsite] = 0;

        targetQue.offer(new int[]{x, y});

        // while (!sourceQue.isEmpty() && !targetQue.isEmpty())

        // The queue will never be empty since the board is infinite, so we can just use while "true"

        while (true) {

            int dist = bfs(sourceQue, sourceVisited, targetVisited);

            if (dist > 0) {

                return dist;

            }      

            dist = bfs(targetQue, targetVisited, sourceVisited);

            if (dist > 0) {

                return dist;

            }

        }

    }


    private int bfs(Queue<int[]> que, int[][] selfVisited, int[][] otherVisited) {

        int[] curr = que.poll();

        

        // dist to the next point

        int dist = selfVisited[curr[0] + offsite][curr[1] + offsite] + 1;

        // System.out.printf("(%d,%d) -> %d", curr[0], curr[1], dist);

        for (int i = 0; i < 8; i++) {

            int nx = curr[0] + dx[i];

            int ny = curr[1] + dy[i];

            

            if (otherVisited[nx + offsite][ny + offsite] != -1) {

                return dist + otherVisited[nx + offsite][ny + offsite];

            }

            if (selfVisited[nx + offsite][ny + offsite] != -1) {

                continue;

            }

            selfVisited[nx + offsite][ny + offsite] = dist;

            que.offer(new int[]{nx, ny});

        }

        return -1;

    }

}

Tuesday, May 24, 2022

711. Number of Distinct Islands II

 一刷 05/2022

Version #1 BFS

参考LC649

重点是把一个island normalize

这里可以hash成一个string

StringBuilder append 加String.format很慢,要避免,最好一个一个append

Runtime: 281 ms, faster than 12.12% of Java online submissions for Number of Distinct Islands II.
Memory Usage: 73.3 MB, less than 16.67% of Java online submissions for Number of Distinct Islands II.

class Solution {

    public int numDistinctIslands2(int[][] grid) {

        // find all grids of an island

        // enumerate all transformations of that island

        // Normalize those transformations by calculating the relative position of the left & top point

        // Sort all the transformations and use the minimum representative to represent the island

        // Use a hash set to deduplicate

        if (grid == null || grid.length == 0 || grid[0] == null || grid[0].length == 0) {

            return 0;

        }

        int rows = grid.length, cols = grid[0].length;

        boolean[][] visited = new boolean[rows][cols];

        Set<String> islands = new HashSet<>();

        for (int y = 0; y < rows; y++) {

            for (int x = 0; x < cols; x++) {

                if (!visited[y][x] && grid[y][x] == 1) {

                    String island = normalize(findIsland(grid, y, x, visited));

                    islands.add(island);

                }

            }

        }

        return islands.size();

    }

    

    private int[] dx = new int[]{1, 0, -1, 0};

    private int[] dy = new int[]{0, -1, 0, 1};

    private List<List<Integer>> findIsland(int[][] grid, int y, int x, boolean[][] visited) {

        List<List<Integer>> island = new ArrayList<>();

        Queue<List<Integer>> que = new ArrayDeque<>();

        que.offer(Arrays.asList(y, x));

        visited[y][x] = true;

        while (!que.isEmpty()) {

            List<Integer> curr = que.poll();

            island.add(curr);

            // go to 4 directions

            for (int i = 0; i < 4; i++) {

                int ny = curr.get(0) + dy[i];

                int nx = curr.get(1) + dx[i];

                // out of boundary

                if (ny < 0 || ny >= grid.length || nx < 0 || nx >= grid[0].length) {

                    continue;

                }

                if (!visited[ny][nx] && grid[ny][nx] == 1) {

                    visited[ny][nx] = true;

                    que.offer(Arrays.asList(ny, nx));

                }

            }

        }

        return island;

    }

    

    private String normalize(List<List<Integer>> island) {

        List<List<List<Integer>>> transformations = new ArrayList<>();

        List<String> strs = new ArrayList<>();

        for (int i = 0; i < 8; i++) {

            transformations.add(new ArrayList<>());

        }

        for (List<Integer> curr : island) {

            int y = curr.get(0);

            int x = curr.get(1);

            transformations.get(0).add(Arrays.asList(x, y));

            transformations.get(1).add(Arrays.asList(-x, y));

            transformations.get(2).add(Arrays.asList(x, -y));

            transformations.get(3).add(Arrays.asList(-x, -y));

            transformations.get(4).add(Arrays.asList(y, x));

            transformations.get(5).add(Arrays.asList(-y, x));

            transformations.get(6).add(Arrays.asList(y, -x));

            transformations.get(7).add(Arrays.asList(-y, -x));

        }

        StringBuilder sb = new StringBuilder();

        for (List<List<Integer>> transformation : transformations) {

            Collections.sort(transformation, new Comparator<List<Integer>>() {

                @Override

                public int compare(List<Integer> a, List<Integer> b) {

                    if (a.get(0) != b.get(0)) {

                        return a.get(0) - b.get(0);

                    }

                    return a.get(1) - b.get(1);

                }

            });

            Integer y0 = transformation.get(0).get(0);

            Integer x0 = transformation.get(0).get(1);

            for (int i = 0; i < transformation.size(); i++) {

                List<Integer> yx = transformation.get(i);

                // y = yx.get(0) - y0

                // x = yx.get(1) - x0

                sb.append("(" +  (yx.get(0) - y0) + "," +  (yx.get(1) - x0) + ")");

            }

            strs.add(sb.toString());

            sb.setLength(0);

        }

        Collections.sort(strs);

        return strs.get(0);

    }

}



Version #2 DFS

Runtime: 115 ms, faster than 45.45% of Java online submissions for Number of Distinct Islands II.
Memory Usage: 67.6 MB, less than 71.21% of Java online submissions for Number of Distinct Islands II.

class Solution {

    class Point implements Comparable<Point> {

        public int x, y;

        public Point(int x, int y) {

            this.x = x;

            this.y = y;

        }

        

        @Override

        public int compareTo(Point p) {

            if (this.y != p.y) {

                return this.y - p.y;

            }

            return this.x - p.x;

        }

        

        @Override

        public String toString() {

            return String.format("(%s,%s)", x, y);

        }

    } 

    public int numDistinctIslands2(int[][] grid) {

        // find all grids of an island

        // enumerate all transformations of that island

        // Normalize those transformations by calculating the relative position of the left & top point

        // Sort all the transformations and use the minimum representative to represent the island

        // Use a hash set to deduplicate

        if (grid == null || grid.length == 0 || grid[0] == null || grid[0].length == 0) {

            return 0;

        }

        int rows = grid.length, cols = grid[0].length;

        boolean[][] visited = new boolean[rows][cols];

        Set<String> islands = new HashSet<>();

        for (int y = 0; y < rows; y++) {

            for (int x = 0; x < cols; x++) {

                if (!visited[y][x] && grid[y][x] == 1) {

                    List<Point> island = new ArrayList<>();

                    visited[y][x] = true;

                    findIsland(grid, y, x, visited, island);

                    String str = normalize(island);

                    islands.add(str);

                }

            }

        }

        return islands.size();

    }

    

    private int[] dx = new int[]{1, 0, -1, 0};

    private int[] dy = new int[]{0, -1, 0, 1};

    private void findIsland(int[][] grid, int y, int x, boolean[][] visited, List<Point> island) {

        island.add(new Point(x, y));

        for (int i = 0; i < 4; i++) {

            int ny = y + dy[i];

            int nx = x + dx[i];

            if (ny < 0 || ny >= grid.length || nx < 0 || nx >= grid[0].length) {

                continue;

            }

            if (!visited[ny][nx] && grid[ny][nx] == 1) {

                visited[ny][nx] = true;

                findIsland(grid, ny, nx, visited, island);

            }

        }

    }

    

    private String normalize(List<Point> island) {

        List<Point>[] transformations = new List[8];

        String[] strs = new String[8];

        for (int i = 0; i < 8; i++) {

            transformations[i] = new ArrayList<>();

        }

        for (Point p : island) {

            int y = p.y;

            int x = p.x;

            transformations[0].add(new Point(x, y));

            transformations[1].add(new Point(-x, y));

            transformations[2].add(new Point(x, -y));

            transformations[3].add(new Point(-x, -y));

            transformations[4].add(new Point(y, x));

            transformations[5].add(new Point(-y, x));

            transformations[6].add(new Point(y, -x));

            transformations[7].add(new Point(-y, -x));

        }

        

        for (int i = 0; i < 8; i++) {

            StringBuilder sb = new StringBuilder();

            Collections.sort(transformations[i]);

            int x0 = transformations[i].get(0).x;

            int y0 = transformations[i].get(0).y;

            for (Point p : transformations[i]) {

                sb.append(String.format("(%s,%s)", p.x - x0, p.y - y0));

            }

            strs[i] = sb.toString();

        }

        Arrays.sort(strs);

        return strs[0];

    }

}

Monday, May 23, 2022

1586. Binary Search Tree Iterator II

 一刷 05/2022

Runtime: 87 ms, faster than 49.06% of Java online submissions for Binary Search Tree Iterator II.
Memory Usage: 71.9 MB, less than 92.60% of Java online submissions for Binary Search Tree Iterator II.

/**

 * Definition for a binary tree node.

 * public class TreeNode {

 *     int val;

 *     TreeNode left;

 *     TreeNode right;

 *     TreeNode() {}

 *     TreeNode(int val) { this.val = val; }

 *     TreeNode(int val, TreeNode left, TreeNode right) {

 *         this.val = val;

 *         this.left = left;

 *         this.right = right;

 *     }

 * }

 */

class BSTIterator {

    // add a array to keep record of all elements that have been visited

    private Stack<TreeNode> stack;

    private List<Integer> visited;

    private int index;

    public BSTIterator(TreeNode root) {

        stack = new Stack<>();

        visited = new ArrayList<>();

        index = 0;

        while (root != null) {

            stack.push(root);

            root = root.left;

        }

    }

    

    public boolean hasNext() {

        return !stack.isEmpty() || index < visited.size();

    }

    

    public int next() {

        int val;

        if (index < visited.size()) {

            val = visited.get(index);

        } else {

            TreeNode curr = stack.pop();

            val = curr.val;

            visited.add(val);

            curr = curr.right;

            while (curr != null) {

                stack.push(curr);

                curr = curr.left;

            }

        }

        index++;

        return val;

    }

    

    public boolean hasPrev() {

        // index is pointing to the next value

        return index - 2 >= 0;

    }

    

    public int prev() {

        return visited.get(--index - 1);

    }

}


/**

 * Your BSTIterator object will be instantiated and called as such:

 * BSTIterator obj = new BSTIterator(root);

 * boolean param_1 = obj.hasNext();

 * int param_2 = obj.next();

 * boolean param_3 = obj.hasPrev();

 * int param_4 = obj.prev();

 */

Thursday, May 19, 2022

658. Find K Closest Elements

一刷 05/2022


Version #2 Binary Search To Find The Left Bound[TODO]

Time O(log(n - k) + k)

Space O(1)

Not working version

有一个反例就是当 mid= 3, mid + k = 6的时候他们同时指向element 2

但是此时需要我们选择larger index

就没懂

index [0,1,2,3,4,5,6,7,8]

arr      [1,1,2,2,2,2,2,3,3]

[1,1,2,2,2,2,2,3,3]
3
3


class Solution {

    public List<Integer> findClosestElements(int[] arr, int k, int x) {

        if (arr == null) {

            return new ArrayList<>();

        }

        // Binary search to find the left bound

        int start = 0, end = arr.length - k;

        System.out.printf("start: %d, end: %d", start, end);

        while (start + 1 < end) {

            int mid = start + (end - start) / 2;

            // arr[mid] and arr[mid + k] there can only 1 be in the final answer

            if (Math.abs(arr[mid] - x) > Math.abs(arr[mid + k] - x)) {

                start = mid + 1;

            } else {

                end = mid;

            }

        }

        System.out.printf("start: %d, end: %d", start, end);

        // ... start end ... start + k, end + k

        if (start + k < arr.length && Math.abs(arr[start] - x) > Math.abs(arr[start + k] - x)) {

            start = end;

        }

        List<Integer> res = new ArrayList<>();

        while (k-- > 0) {

            res.add(arr[start]);

            start++;

        }

        return res;

    }

}


Version #1 Binary Search + Sliding window

一遍bug free就过了,我真棒

重点是在算insertion index的时候考虑到各种Corner case

Time O(logN + k)

Space O(1)

Runtime: 5 ms, faster than 75.90% of Java online submissions for Find K Closest Elements.

Memory Usage: 62.6 MB, less than 40.35% of Java online submissions for Find K Closest Elements. 

class Solution {

    public List<Integer> findClosestElements(int[] arr, int k, int x) {

        if (arr == null) {

            return new ArrayList<>();

        }

        // It's possible that x is not in the array

        // Find the insertion index of x in array -> find the 1st index where arr[index] >= x

        int insertionIndex = findIndex(arr, x);

        int left = insertionIndex - 1, right = insertionIndex;

        while (k > 0) {

            int leftDiff = left >= 0 ? x - arr[left] : Integer.MAX_VALUE;

            int rightDiff = right < arr.length ? arr[right] - x : Integer.MAX_VALUE;

            if (leftDiff <= rightDiff) {

                left--;

            } else {

                right++;

            }

            k--;

        }

        // 1,2,3,4,5  x = 3 -> insertinIndex = 2, k = 4

        //   l r

        //   l   r     k = 3

        //  l    r     k = 2

        //  l      r   k = 1

        //l        r   k = 0

        List<Integer> res = new ArrayList<>();

        for (int i = left + 1; i < right; i++) {

            res.add(arr[i]);

        }

        return res;

    }

    

    private int findIndex(int[] arr, int x) {

        int start = 0, end = arr.length - 1;

        while (start + 1 < end) {

            int mid = start + (end - start) / 2;

            if (arr[mid] < x) {

                start = mid + 1;

            } else {

                end = mid;

            }

        }

        if (arr[start] >= x) {

            return start;

        }

        if (arr[end] >= x) {

            return end;

        }

        // All elements are smaller than x, insert to the end of the array

        return arr.length;

    }

}

Wednesday, May 18, 2022

702. Search in a Sorted Array of Unknown Size

一刷 05/2022

Time O(logk) -> k is the index of the target number

Space O(1) 

Runtime: 2 ms, faster than 91.48% of Java online submissions for Search in a Sorted Array of Unknown Size.
Memory Usage: 42.9 MB, less than 98.82% of Java online submissions for Search in a Sorted Array of Unknown Size.


/**

 * // This is ArrayReader's API interface.

 * // You should not implement it, or speculate about its implementation

 * interface ArrayReader {

 *     public int get(int index) {}

 * }

 */


class Solution {

    public int search(ArrayReader reader, int target) {

        // Find a upper bound of the range in which we can search for the target

       int end = 1;

        while (reader.get(end) < target) {

            end = end << 1;

        }

        int start = end >> 1;

        while (start <= end) {

            int mid = start + (end - start) / 2;

            if (reader.get(mid) == target) {

                return mid;

            }

            if (reader.get(mid) < target) {

                start = mid + 1;

            } else {

                end = mid - 1;

            }

        }

        return -1;

    }

}


144 · Interleaving Positive and Negative Numbers [LintCode]

 一刷


我觉得做法是对的但是没有过OC

感觉OC有问题

Time O(n)

Space O(1)

public class Solution {
/**
* @param a: An integer array.
* @return: nothing
*/
public void rerange(int[] a) {
// [-1, -2, -3, 4, 5, 6]
if (a == null) {
return;
}
int posCnt = 0;
for (int num : a) {
if (num > 0) {
posCnt++;
}
}
int negCnt = a.length - posCnt;
int posStart, negEnd;
if (posCnt == negCnt) {
posStart = 1;
negEnd = a.length - 2;
} else if (posCnt > negCnt) {
posStart = 0;
negEnd = a.length - 2;
} else {
posStart = 1;
negEnd = a.length - 1;
}
while (posStart < a.length && negEnd >= 0) {
while (posStart < a.length && a[posStart] > 0) {
posStart += 2;
}
while (negEnd >= 0 && a[negEnd] < 0) {
negEnd -= 2;
}
if (posStart < a.length && negEnd >= 0) {
int temp = a[posStart];
a[posStart] = a[negEnd];
a[negEnd] = temp;
posStart += 2;
negEnd -= 2;
}
}
}
}

143 · Sort Colors II [LintCode]

一刷 05/2022

Time O(nlogk)

Space O(1)

public class Solution {
/**
* @param colors: A list of integer
* @param k: An integer
* @return: nothing
*/
public void sortColors2(int[] colors, int k) {
// Every time devide the color by 2 and partition the colors
// Then we got O(nlogk) time complexity
if (colors == null) {
return;
}
sortColorsHelper(colors, 0, colors.length - 1, 1, k);
}

private void sortColorsHelper(int[] colors, int start, int end, int kStart, int kEnd) {
if (kStart == kEnd) {
return;
}
// k/2 k - k/2
// 1111 22222
// when k = 2, we want sort [start right] [left end]
// when k = 3, we wnat sort
int pivot = (kStart + kEnd) / 2; // the pivot color
int left = start, right = end;
while (left <= right) {
while (left <= right && colors[left] <= pivot) {
left++;
}
while (left <= right && colors[right] > pivot) {
right--;
}
if (left <= right) {
int temp = colors[left];
colors[left] = colors[right];
colors[right] = temp;
left++;
right--;
}
}
// left is the first index that has color > pivot
sortColorsHelper(colors, start, left - 1, kStart, pivot);
sortColorsHelper(colors, left, end, pivot + 1, kEnd);
}
}

Tuesday, May 17, 2022

2149. Rearrange Array Elements by Sign

一刷 05/2022


Time O(n)

Space O(n) 

Runtime: 7 ms, faster than 58.43% of Java online submissions for Rearrange Array Elements by Sign.
Memory Usage: 230.7 MB, less than 5.18% of Java online submissions for Rearrange Array Elements by Sign.

class Solution {

    public int[] rearrangeArray(int[] nums) {

        if (nums == null || nums.length == 0) {

            return nums;

        }

        int[] res = new int[nums.length];

        int pos = 0, neg = 1;

        for (int num : nums) {

            if (num < 0) {

                res[neg] = num;

                neg += 2;

            } else {

                res[pos] = num;

                pos += 2;

            }

        }

        return res;

    }

}

561. Array Partition I

一刷 05/2022

Time O(nlogn)

Space O(1)


Runtime: 13 ms, faster than 85.57% of Java online submissions for Array Partition I.
Memory Usage: 44 MB, less than 97.44% of Java online submissions for Array Partition I.

 class Solution {

    public int arrayPairSum(int[] nums) {

        // make them as close as possible

        if (nums == null || nums.length == 0) {

            return 0;

        }

        Arrays.sort(nums);

        int sum = 0;

        for (int i = 0; i < nums.length; i += 2) {

            sum += nums[i];

        }

        return sum;

    }

}