力扣560 [和为 K 的子数组], 209 [长度最小的子数组],1037 [有效的回旋镖]

171 阅读1分钟

560 题目地址: leetcode.com/problems/su…

给定一个数组,再给定一个数k,问这个数组中有多少个子数组其和为k。

容易想到用前缀和。遍历前缀和的同时可以用一个哈希表记录每个前缀和出现了多少次,同时做计数即可。代码如下:

import java.util.HashMap;
import java.util.Map;

public class Solution {
    public int subarraySum(int[] nums, int k) {
        if (nums == null || nums.length == 0) {
            return 0;
        }
        
        int[] preSum = new int[nums.length + 1];
        for (int i = 0; i < nums.length; i++) {
            preSum[i + 1] = preSum[i] + nums[i];
        }
        
        int res = 0;
        // key代表前缀和,value代表该前缀和出现的次数
        Map<Integer, Integer> map = new HashMap<>();
        for (int i = 0; i < preSum.length; i++) {
        	// 如果前缀和preSum[i] - k出现过,说明存在子数组和为k,就累加进res
            if (map.containsKey(preSum[i] - k)) {
                res += map.get(preSum[i] - k);
            }
            // 更新前缀和出现的次数
            map.put(preSum[i], map.getOrDefault(preSum[i], 0) + 1);
        }
        
        return res;
    }
}

题目地址: leetcode.com/problems/mi…

给定一个正整数数组,再给定一个正数s ,求数组的最短子数组的和大于等于s ,返回其长度。

思路是,开快慢双指针i 和j ,并开一个变量来维护[ i : j ] 这个区间内的和(包括端点)。如果这个区间和大于等于s ,则更新最短长度,并让i 后移,同时区间和减去A [ i ] ;如果这个区间和小于s ,则右移j 。代码如下:

public class Solution {
    public int minSubArrayLen(int s, int[] nums) {
        int res = nums.length + 1, sum = 0;
        for (int i = 0, j = 0; j < nums.length; ) {
        	// sum维护nums[i, ..., j]的和
            sum += nums[j];
            // 如果和大于等于s,说明区间[i : j]满足条件,更新长度,并让i后移
            while (sum >= s) {
                res = Math.min(res, j - i + 1);
                sum -= nums[i];
                i++;
            }
            
            // 上面的循环已经把以nums[j]结尾的满足条件的子数组都算过了,则让j后移
            j++;
        }
        
        // res未得到更新,则说明不存在解,返回0;否则返回res
        return res == nums.length + 1 ? 0 : res;
    }
}

题目地址: leetcode.com/problems/va…

给定平面三个点的坐标,问其是否不在一条直线上。如果不在一条直线上则返回true。

两个向量( x 1 , y 1 ) , ( x 2 , y 2 ) 共线等价于行列式

image.png

public class Solution {
    public boolean isBoomerang(int[][] points) {
        int[] x = new int[2], y = new int[2];
        for (int i = 1; i < points.length; i++) {
            x[i - 1] = points[i][0] - points[0][0];
            y[i - 1] = points[i][1] - points[0][1];
        }
        
        return x[0] * y[1] != x[1] * y[0];
    }
}