算法題練習(7.28~8.4)

1. 二叉樹的右視圖 https://leetcode.com/problems/binary-tree-right-side-view/
2. 二叉搜索樹與與雙向鏈表   https://www.nowcoder.com/practice/947f6eb80d944a84850b0538bf0ec3a5?tpId=13&tqId=11179&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking
3. 給定一個有序數組,數字可能會重複,沒找到就輸出-1(要求時間複雜度爲logn,這其實)
    1. 查找第一個值等於給定值的元素的位置 input: 數組 3,4,6,6,6,7,11 給定值6 output:2
    2. 查找最後一個值等於給定值的元素的位置 input: 數組 3,4,6,6,6,7,11 給定值6 output:4
    3. 查找第一個大於等於給定值的元素的位置 input: 數組 3,4,6,6,6,7,11 給定值5 output: 2
    4. 查找最後一個小於等於給定值的元素的位置 input: 數組 3,4,6,6,6,7,11 給定值5 output: 1
4. 堆排序
5. 給定一個數組,數字均爲整數,有正數和負數,數字可能會重複,要求輸出該數組按絕對值排序後的結果,且正數在後,負數在前。input:數組 0, 1,-1,2,-2,3,4 output: 0,-1,1,-2,2,3,4

1 二叉樹的右視圖

ArrayList<Integer> res = new ArrayList<>();
        if (root == null) {
            return res;
        }

        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);

        while (!queue.isEmpty()) {
            int size = queue.size();
            for (int i = 0; i < size; i++) {
                TreeNode node = queue.poll();
                if (i == (size - 1)) {
                    res.add(node.val);
                }
                if (node.left != null) {
                    queue.offer(node.left);
                }
                if (node.right != null){
                    queue.offer(node.right);
                }
            }
        }

        return res;

2 二叉樹與雙向鏈表

2.1 方法1

  1. 生成一個隊列,中序遍歷二叉樹,將節點依次放入;
  2. 隊列元素依次彈出,並按照彈出的順序重連所有的節點;
public TreeNode Convert(TreeNode pRootOfTree) {
        Queue<TreeNode> queue = new LinkedList<TreeNode>();
        inOrderTuQueue(pRootOfTree, queue);
        if (queue.isEmpty()) {
            return pRootOfTree;
        }

        pRootOfTree = queue.poll();
        TreeNode pre = pRootOfTree;
        pre.left = null;
        TreeNode cur = null;
        while (!queue.isEmpty()) {
            cur = queue.poll();
            pre.right = cur;
            cur.left = pre;
            pre = cur;
        }
        
        pre.right = null;
        return pRootOfTree

    }

    public void inOrderTuQueue(TreeNode head, Queue<TreeNode> queue) {
        if (head == null) {
            return;
        }
        inOrderTuQueue(head.left, queue);
        queue.offer(head);
        inOrderTuQueue(head.right, queue);

    }

2.2 遞歸

 class ReturnType {
        private TreeNode start;
        private TreeNode end;

        public ReturnType(TreeNode start, TreeNode end) {
            this.start = start;
            this.end = end;
        }
    }

    public ReturnType process(TreeNode head) {
        if (head == null) {
            return new ReturnType(null, null);
        }
        ReturnType leftList = process(head.left);
        ReturnType rightList = process(head.right);

        if (leftList.end != null) {
            leftList.end.right = head;
        }
        head.left = leftList.end;
        head.right = rightList.start;

        if (rightList.start != null) {
            rightList.start.left = head;
        }

        return new ReturnType(leftList.start != null ? leftList.start : head,
                rightList.end != null ? rightList.end : head);

    }

    public TreeNode Convert(TreeNode pRootOfTree) {
        if (pRootOfTree == null) {
            return null;
        }

        return process(pRootOfTree).start;
    }

3 堆排序

  • 時間複雜度 O(nlogn)
  • 原地排序
public class HeapSort {
    public static int[] sort(int[] sourceArray) {
        int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);
        int len = arr.length;
        buildHeap(arr, len);

        for (int i = len - 1; i > 0; i--) {
            swap(arr, 0, i);
            len--;
            heapify(arr, 0, len);
        }

        return arr;
    }

    private static void buildHeap(int[] arr, int len) {
        for (int i = (int) Math.floor(len / 2); i >= 0; i--) {
            heapify(arr, i, len);
        }
    }

    private static void heapify(int[] arr, int i, int len) {
        int left = 2 * i + 1;
        int right = 2 * i + 2;
        int largest = i;

        if (left < len && arr[left] > arr[largest]) {
            largest = left;
        }
        if (right < len && arr[right] > arr[largest]) {
            largest = right;
        }

        if (largest != i) {
            swap(arr, i, largest);
            heapify(arr, largest, len);
        }

    }

    private static void swap(int[] arr, int i, int largest) {
        int temp = arr[i];
        arr[i] = arr[largest];
        arr[largest] = temp;
    }

    public static void main(String[] args) {
        int[] arr = {5, 7, 8, 4, 9, 10, 20};
        int[] res = sort(arr);
        System.out.println(Arrays.toString(res));
    }

}

4 在排序數組中查找元素的第一個和最後一個位置

https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array/

public class SearchRange {

    private int leftBound(int[] nums, int target) {
        if (nums.length == 0) {
            return -1;
        }
        int left = 0;
        int right = nums.length;

        while (left < right) {
            int mid = left + (right - left) / 2;
            if (nums[mid] == target) {
                right = mid;
            } else if (nums[mid] < target) {
                left = mid + 1;
            } else if (nums[mid] > target) {
                right = mid;
            }
        }

        if (left == nums.length) {
            return -1;
        }

        return nums[left] == target ? left : -1;

    }

    private int rightBound(int[] nums, int target) {
        if (nums.length == 0) {
            return -1;
        }
        int left = 0;
        int right = nums.length;

        while (left < right) {
            int mid = (left + right) / 2;
            if (nums[mid] == target) {
                left = mid + 1;
            } else if (nums[mid] < target) {
                left = mid + 1;
            } else if (nums[mid] > target) {
                right = mid;
            }
        }

        if (left == 0) {
            return -1;
        }

        return nums[left - 1] == target ? (left - 1) : -1;


    }


    public int[] searchRange(int[] nums, int target) {
        int[] targetRange = {-1, -1};

        int left = leftBound(nums, target);
        if (left == -1) {
            return targetRange;
        }
        targetRange[0] = left;
        targetRange[1] = rightBound(nums, target);
        return targetRange;
    }

    public static void main(String[] args) {
        int[] nums = {1, 2, 2, 4};
        int val = 2;
        int[] res = new SearchRange().searchRange(nums,val);
        System.out.println(Arrays.toString(res));
    }

}

5 排序

  • . 給定一個數組,數字均爲整數,有正數和負數,數字可能會重複,要求輸出該數組按絕對值排序後的結果,且正數在後,負數在前
  public static void main(String[] args) {
        int[] nums = {0, 1, -1, 2, -2, 3, 4};
        Arrays.sort(nums);
        // System.out.println(Arrays.toString(nums));

        LinkedList<Integer> linkedList = new LinkedList<>();
        for (int num : nums) {
            if (num >= 0) {
                linkedList.add(num);
            }
        }

        System.out.println("linkedList: " + linkedList);

        for (int num : nums) {
            if (num < 0) {
                for (int i = 0; i < linkedList.size(); i++) {
                    int temp = linkedList.get(i);
                    if (-num <=temp) {
                        linkedList.add(i, num);
                        break;
                    }
                }
            }
        }

        for (int i = 0; i < linkedList.size(); i++) {
            nums[i] = linkedList.get(i);
        }

        System.out.println(Arrays.toString(nums));

    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章