LeetCode热题100道-day04

55 阅读2分钟

LeetCode热题100道-day04

1. 搜索旋转排序数组

33. 搜索旋转排序数组

  • 要求是O(logN),所有使用二分法,数组是局部有序的。
public int search(int[] nums, int target) {  
    if (nums == null || nums.length == 0){  
        return -1;  
    }  
    int start = 0;  
    int end = nums.length-1;  
    int mid;  
    // 等于  
    while (start<=end){  
        mid = start + (end-start)/2;  
        if (nums[mid] == target){  
            return mid;  
        }  
        // 前半部分有序,注意小于等于  
        if (nums[start] <= nums[mid]){  
            if (target >=nums[start] && target < nums[mid]){  
                end=mid-1;  
            }else {  
                start = mid+1;  
            }  
        }else {  
            if (target <= nums[end] && target>nums[mid]){  
                start = mid+1;  
            }else {  
                end = mid -1;  
            }  
        }  
  
    }  
    return -1;  
}

2. 在排序数组中查找元素的第一个和最后一个位置

34. 在排序数组中查找元素的第一个和最后一个位置

  • 二分法,定义两个方法,一个找第一个指定元素位置,一个找最后一个指定元素位置
    public int[] searchRange(int[] nums, int target) {  
        int len = nums.length;  
        int first = findFirst(nums, target, len);  
        int last = findLast(nums, target, len);  
        return new int[]{first, last};  
    }  
  
    private int findFirst(int[] nums, int target, int len) {  
        int start = 0;  
        int end = len - 1;  
        int mid;  
        while (start <= end) {  
            mid = start + (end - start) / 2;  
            if (target == nums[mid]) {  
                if (mid > 0 && nums[mid - 1] == nums[mid]) {  
                    end = mid - 1;  
                } else {  
                    return mid;  
                }  
            } else if (target > nums[mid]) {  
                start = mid + 1;  
            } else if (target < nums[mid]) {  
                end = mid - 1;  
            }  
        }  
        return -1;  
    }  
  
    private int findLast(int[] nums, int target, int len) {  
        int start = 0;  
        int end = len - 1;  
        int mid;  
        while (start <= end) {  
            mid = start + (end - start) / 2;  
            if (target == nums[mid]) {  
                if (mid < len - 1 && nums[mid + 1] == nums[mid]) {  
                    start = mid + 1;  
                } else {  
                    return mid;  
                }  
            } else if (target > nums[mid]) {  
                start = mid + 1;  
            } else if (target < nums[mid]) {  
                end = mid - 1;  
            }  
        }  
        return -1;  
    }  
}

3. 组合总和

39. 组合总和

  • 还不能理解
class Solution {
    public List<List<Integer>> combinationSum(int[] candidates, int target) {
        List<List<Integer>> ans = new ArrayList<List<Integer>>();
        List<Integer> combine = new ArrayList<Integer>();
        dfs(candidates, target, ans, combine, 0);
        return ans;
    }

    public void dfs(int[] candidates, int target, List<List<Integer>> ans, List<Integer> combine, int idx) {
        if (idx == candidates.length) {
            return;
        }
        if (target == 0) {
            ans.add(new ArrayList<Integer>(combine));
            return;
        }
        // 直接跳过
        dfs(candidates, target, ans, combine, idx + 1);
        // 选择当前数
        if (target - candidates[idx] >= 0) {
            combine.add(candidates[idx]);
            dfs(candidates, target - candidates[idx], ans, combine, idx);
            combine.remove(combine.size() - 1);
        }
    }
}

4. 找到最近的有相同 X 或 Y 坐标的点(每日一题)

1779. 找到最近的有相同 X 或 Y 坐标的点

  • 直接遍历,当符合条件x相对、y相等、xy都相等,就计算曼哈顿距离,新距离比旧距离小旧更新最小值和数组下标,等于也不用更新
public int nearestValidPoint(int x, int y, int[][] points) {  
    int ans = -1;  
    int mi = 10000;  
    for (int i = 0; i < points.length; i++) {  
            if (x == points[i][0] || y == points[i][1]) {  
                int mhd = Math.abs(x - points[i][0]) + Math.abs(y - points[i][1]);  
                if (mhd < mi){  
                    mi = mhd;  
                    ans = i;  
                }  
            }  
    }  
    return ans;  
}