快手测开面试算法

283 阅读1分钟

面试算法总结(1)

1、搜索二维矩阵 II

  • 面试思路:
    • 局部二分找边界
    • 递归遍历查找
    class Solution {
        public boolean searchMatrix(int[][] matrix, int target) {
            int rows = matrix.length;
            if (rows == 0) return false;
            int cols = matrix[0].length;
            int l = 0, r = cols - 1;
            while (l <= r){
                int mid = l + (r - l) / 2;
                if(matrix[0][mid] == target){
                    return true;
                }else if (matrix[0][mid] > target){
                    r = mid - 1;
                }else {
                    l = mid + 1;
                }
            }
            int col = r;
            l = 0;
            r = rows - 1;
            while (l <= r){
                int mid = l + (r - l) / 2;
                if(matrix[mid][0] == target){
                    return true;
                }else if (matrix[mid][0] > target){
                    r = mid - 1;
                }else {
                    l = mid + 1;
                }
            }
            int row = r;
            for (int i = 0; i <= row; i++) {
                for (int j = 0; j <= col; j++) {
                    if (matrix[i][j] == target){
                        return true;
                    }
                }
            }
            return false;
        }
    }
    
  • 标准解法:
    • 将二维升序数组,转换为以右上角为根的二叉搜索树
    class Solution {
        public boolean searchMatrix(int[][] matrix, int target) {
            int m = matrix.length;
            if (m == 0) return false;
            int n = matrix[0].length;
            int row = 0, col = n - 1;
            while (row < m && col >= 0) {
                if (matrix[row][col] == target){
                    return true;
                }else if (matrix[row][col] > target){
                    col --;
                }else {
                    row ++;
                }
            }
            return false;
        }
    }
    

2、数组中的第K个最大元素

  • 面试思路
    • 快排的思想,对数组进行快排,如果有某个数右边大于它的数为k-1个,则该数为第k大的数。
    • 复杂度 nlognnlogn
    class Solution {
    
        public int findKthLargest(int[] nums, int k) {
            return quickSort(nums, 0, nums.length - 1, nums.length - k);
        }
    
        private int quickSort(int[] nums, int l, int r, int index) {
            if (l < r) {
                int sort = sort(nums, l, r);
                if (sort == index) {
                    return nums[sort];
                } else if (sort < index) {
                    //本次快排的数小于目标值,继续向快排右侧寻找
                    return quickSort(nums, sort + 1, r, index);
                } else {
                    return quickSort(nums, l, sort - 1, index);
                }
            }
            return nums[l];
        }
    
        private int sort(int[] nums, int start, int end) {
            int cur = nums[start];
            while (start < end) {
                while (end > start && nums[end] > cur) {
                    end--;
                }
                nums[start] = nums[end];
                while (start < end && nums[start] <= cur) {
                    start++;
                }
                nums[end] = nums[start];
            }
            nums[end] = cur;
            return end;
        }
    }
    
  • 标准解法:
    • 维护一个k大小的小顶堆
    • 复杂度 nlogknlogk
    class Solution {
        public int findKthLargest(int[] nums, int k) {
            PriorityQueue<Integer> queue = new PriorityQueue<>();
            for (int item : nums) {
                if (queue.size() < k){
                    queue.offer(item);
                }else {
                    if (item > queue.peek()){
                        queue.poll();
                        queue.offer(item);
                    }
                }
            }
            return queue.peek();
        }
    }    
    

3、99个无序数列,数值范围为1-100,无重复,寻找缺失的元素。

  • 最优思路
    • 先求1-100的累加和,O(n) 遍历数组
    • 每次向减,答案即为结果