代码随想录算法训练营第一天 | 数组part01

总结:

 第一天比较轻松,主要是适应刷题的节奏。 虽然都是之前做过的题目,但是重新复习一遍,又加深了对二分法和双指针的理解。 很久没有做笔记了,记录比较简短和潦草。

后续需要解决的问题:当我拿到一个题目时,如果快速的判断,需要使用哪种算法来解题。

704. 二分查找 - 力扣(LeetCode)数组理论基础 

关键词: 连续内存空间, 相同类型数据

在C++中,1-D and 2-D 数组是连续分布的。

In Java, a 2D array is implemented as an array of object references. This means that each row of the 2D array is a separate 1D array. While each individual 1D array is stored contiguously in memory, the 2D array itself is not. 

704. 二分查找 - 力扣(LeetCode)

二分法最基础的题目。学习重点在于理解 区间定义, 

区间定义:是循环不变量。不同的区间定义,影响了边界条件的处理 。

  • [left, right] 左闭右闭
  • //左闭右闭
    class Solution {
        public int search(int[] nums, int target) {
            int l = 0;
            int r = nums.length - 1;  //区间为[0, mums.length - 1]
            while( l <= r){       // (l <= r) 是合法区间, 比如[1,1]
                int mid = l + (r-l)/2;     //避免overflow
                if(nums[mid] == target){
                    return mid;
                }else if(nums[mid] > target){
                    r = mid - 1;    // mid一定不包含在区间里,所以right更新为mid - 1
                }else{
                    l = mid + 1;
                }
            }
            return -1;
        }
    }
  • [left, right ) 左闭右开
    // 左闭右开
    class Solution {
        public int search(int[] nums, int target) {
            int l = 0;
            int r = nums.length;   //区间为[0, mums.length)
            while( l < r){
                int mid = l + (r-l)/2;
                if(nums[mid] == target){
                    return mid;
                }else if(nums[mid] > target){
                    r = mid ;    
                }else{
                    l = mid + 1;
                }
            }
            return -1;
        }
    }

27. 移除元素 - 力扣(LeetCode)

  • 暴力解法很直观, 用两层for loop, outer loop 遍历所有元素, inner loop 把该元素之后的元素前移(如果该元素需要删除)
    class Solution {
        public int removeElement(int[] nums, int val) {
            int size = nums.length;
            for(int i = 0; i < size; i++){
                if( nums[i] == val){
                    for(int j = i + 1; j < size; j++){
                        nums[j-1] = nums[j];
                    }
                    i--;
                    size--;
                }
            }
            return size;
        }
    }
  • 双指针 (快慢指针): 快指针寻找新数组的元素,如果找到不等于val的元素,赋值给新数组。慢指针更新新数组的下标。
    • 重点在于如何定义快慢指针,以及指针移动的条件
  • class Solution {
        public int removeElement(int[] nums, int val) {
            int size = nums.length;
            int j = 0;
            // j 用来更新新数组的下标
            for(int i = 0; i < size; i++){
                if (nums[i] != val){ 
                    nums[j++] = nums[i]; 
                }
            }
            return j;
        }
    }

977.有序数组的平方

观察数组: 因为数组中可能包含负数, 最大的平方值只能在数组的两端

解题思路: 需要两个指针,分别在左端和右端,不断比较大小,并向中间移动,把当前最大值更新到新数组

class Solution {
    public int[] sortedSquares(int[] nums) {
        int n = nums.length;
        int[] ans = new int[n];
        for(int i = 0, j = n - 1; i <= j; ){
            if(nums[i] * nums[i] < nums[j] * nums[j]){
                ans[n - 1] = nums[j] * nums[j];
                j--;
            }else{
                ans[n - 1] = nums[i] * nums[i];
                i++;
            }
            n--;
        }
        return ans;
    }
}

你可能感兴趣的:(代码随想录算法训练营,算法)