这个专栏 我将分享每日做的算法题的解题思路 秋招加油!
这是第四天 !!
010 和为 k 的子数组
题目
AC代码
class Solution {
public int subarraySum(int[] nums, int k) {
int result = 0;
for (int i = 0; i < nums.length; i++) {
int sum = 0;
int right = i;
while(right<nums.length){
sum += nums[right];
right++;
if(sum == k){
result++;
}
}
}
return result;
}
}
这道题由于可以输入负整数,所以我们需要全部遍历一次。
我采用的是 枚举 的方法,当然更低的时间复杂度则是 前缀和 的方法。
011 0 和 1 个数相同的子数组
题目
AC代码
class Solution {
public int findMaxLength(int[] nums) {
Map<Integer,Integer> map = new HashMap<>();
int maxlength = 0;
int count = 0;
map.put(count,-1);
for(int i = 0;i<nums.length;i++){
if(nums[i] == 1){
count++;
}
else{
count--;
}
if(map.containsKey(count)){
int length = map.get(count);
maxlength = Math.max(maxlength,i-length);
}
else{
map.put(count,i);
}
}
return maxlength;
}
}
这道题使用枚举的方法会导致时间超限,可以采用前缀和的方法解决。
可以把0当成-1,1当成1,题目就可以巧妙的变为求和为0的最长数组区间,这跟之前的题目就很像了。只要能想到使用前缀和解决,这道题就不会很难。
012 左右两边子数组的和相等
题目
AC代码
public int pivotIndex(int[] nums) {
int result = -1;
int total = 0;
for (int i = 0; i < nums.length; i++) {
total += nums[i];
}
int sum = 0;
for(int i = 0;i<nums.length;i++){
sum+=nums[i];
if(2*sum - nums[i] == total){
result = i;
break;
}
}
return result;
}
根据题目要求可以知道,中心下标的左侧和等于右侧和,所以中心下标的左侧和 * 2 + 中心下标 = total ,等同于 中心下标的前缀和 * 2 - 中心下标 = total。
所以这道题也是求前缀和,只要找到关系式,做起来就不难了。
013 二维子矩阵的和
题目
AC代码
class NumMatrix {
private int[][] data;
public NumMatrix(int[][] matrix) {
this.data = matrix;
}
public int sumRegion(int row1, int col1, int row2, int col2) {
int sum = 0;
for(int i=row1;i<=row2;i++){
for(int j=col1;j<=col2;j++){
sum+=data[i][j];
}
}
return sum;
}
}
这道题可以直接枚举的方式解决,也可以使用前缀法的方法解决。
那些看似不起波澜的日复一日,会突然在某一天,让人看到坚持的意义。