704. 二分查找

思路:首先把 left 、mid 、 right 都定义出来。mid 的赋值,左右指针的跳转都在循环内完成,注意要 left=mid+1,right = mid-1,不然有的用例会超时,循环条件则是 right ≥ left 不然藏在边界的 target 就查不到了。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
class Solution {
    public int search(int[] nums, int target) {
        int left = 0, right = nums.length-1, mid;
        while(right >= left ){
            mid = (right-left)/2+left;
            if(target == nums[mid]) return mid;
            else if(target > nums[mid]) left = mid+1;
                else    right = mid-1;
        }
        return -1;
    }
}

27. 移除元素

暴力解法:需要注意,i–;是因为既然当前值为 val 的点的右边所有点一切都左移了一位,所以现在的 i 指向的是已删除(被覆盖)的位置,该位置补了后面那位没被扫描的数字,而该次循环结束就要 i++了,所以会指向这个没扫描的下一个进行扫描,就漏掉一个了。还有一个就是无限循环容易发生是因为 for 循环条件不能是 < length。而应该是 < len 这个自定义的,会随着更新而更新。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
class Solution {
    public int removeElement(int[] nums, int val) {
        int len = nums.length;
        for(int i = 0; i < len; i++)
            if(nums[i] == val){
                for(int j = i; j < len-1; j++)
                    nums[j] = nums[j+1];
                len--;
                i--;
            }
            return len;
    }
}

快慢指针法:fast 位置是 val 值,就 fast++,不是 val 值就 nums[slow] = nums[fast],slow 后移一位,为了不影响 非val 的值,并且slow可以计数(非 val 个数)。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
class Solution {
    public int removeElement(int[] nums, int val) {
        int slow = 0, fast = 0;
        for(; fast < nums.length; fast++)
            if(nums[fast] != val){
                nums[slow] = nums[fast];
                slow++;
            }    
        return slow;
    }
}

977. 有序数组的平方

思路:暴力就是先平方再 arrays.sort( ); 但是时间复杂度为 O(n)+nlogn; 所以这么解不行,用双指针的方法要注意,一定要从两头找最大的放入新数组的最右侧,因为两头只能找最大,最小的有可能类似:{-3,0,3},最小在中间。注意循环条件是 left ≤ right,而不是 left < right,因为有边界要处理。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
class Solution {
    public int[] sortedSquares(int[] nums) {
        int left = 0, right = nums.length-1,i=nums.length-1;
        int[] array = new int[nums.length];
        while(left <= right)
            if(nums[left]*nums[left] > nums[right]*nums[right])
                array[i--] = nums[left]*nums[left++];
            else
                array[i--] = nums[right]*nums[right--];
        return array;
    }
}

209. 长度最小的子数组

思路:滑动窗口,这样写法虽然时间复杂度是 O(n),但是效率比另一种 O(n^2) 要低很多,另一种在 for 循环嵌套一个 while 循环,让达到 ≥ target 的 sum 一直减去 nums[left] ,而 sum 不需要反复初始化为 0. 注意循环自增 end。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
//双指针
class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int begin = 0, end = 0, sum = 0, min = Integer.MAX_VALUE;
        for(; end < nums.length; end++){
            sum += nums[end];
            if(sum >= target){
                min = Math.min(min,end-begin+1);
                sum = 0;
                end = begin;
                begin++;
            }
        }
        return min == Integer.MAX_VALUE ? 0 : min;
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
//滑动窗口
class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int begin = 0, end = 0, sum = 0, min = Integer.MAX_VALUE;
        for(; end < nums.length; end++){
            sum += nums[end];
            while(sum >= target){
                min = Math.min(min,end-begin+1);
                sum -= nums[begin++];
            }       
        }
        return min == Integer.MAX_VALUE ? 0 : min;
    }
}

59. 螺旋矩阵 II

思路:

  1. 先模拟整个一圈的流程,再去写外层循环,循环次数可以由 n/2 来确定,但此时有个问题,n 为奇数则中间 array[n/2][n/2] 需要单独赋值,而 n 为偶数不需要。
  2. 还有在判断的时候很容易搞混什么适合走的是 x ,什么时候走的是 y。
  3. 在往内圈走的时候很容易碰到一个问题就是:n 需不需要 n– ?其实设置一个偏移量 offset 就行了,因为如果 n— 那么在第三、四个循环解决不了少走一个格子的问题。
  4. 设置 startX、startY 是为了走下一圈的时候能顺利切换。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class Solution {
    public int[][] generateMatrix(int n) {
        int[][] array = new int[n][n]; 
        int x, y, startX = 0, startY = 0, num = 1, circle = n / 2, offset = 0;
        while(circle-- > 0){
            x = startX;
            y = startY;
            for(; y + offset < n-1; y++){
                array[x][y] = num++;
            }
            for(; x + offset < n-1; x++){
                array[x][y] = num++;
            }
            for(; y - offset > 0; y--){
                array[x][y] = num++;
            }
            for(; x - offset > 0; x--){
                array[x][y] = num++;
            }
            startX++;
            startY++;
            offset++;
        }
        if(n % 2 == 1)array[n/2][n/2] = num;
        return array;
    }
}

持续更新…….
如有错误,敬请斧正!!!