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;

    }

}