代码随想录算法训练营第二天

LeetCode/卡码网题目

  • 209. 长度最小的子数组
  • 59. 螺旋矩阵 II
  • 58. 区间和(第九期模拟笔试)
  • 44. 开发商购买土地(第五期模拟笔试)
  • 卡码网周赛
    • 227.藻类的总重量
    • 228.吃豆人游戏
    • 229.平衡子串的长度
  • 总结
  • 往期打卡


209. 长度最小的子数组

题目:

给定一个含有 n 个正整数的数组和一个正整数 target

找出该数组中满足其总和大于等于 target 的长度最小的 子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度**。**如果不存在符合条件的子数组,返回 0

思路:

滑动窗口,始终保持在边界取临界值进行比较

代码:

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int sum = 0;
        int res = Integer.MAX_VALUE;
        for(int i=0,j=-1;i<nums.length;i++){
            sum+=nums[i];
            while(sum>=target){
                int l = i-j;
                sum-= nums[++j];
                res = res>l?l:res;
            }
        }
        if(res==Integer.MAX_VALUE) return 0;
        else return res;
    }
}

59. 螺旋矩阵 II

题目:

给你一个正整数 n ,生成一个包含 1n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix

思路:

模拟,需要找到每一圈以及各圈间跳转的规律

代码:

class Solution {
    public int[][] generateMatrix(int n) {
        int[][] res = new int[n][n];
        int len = n-1;
        int num = 1;
        int mid = n/2;
        for(int i=0;i<mid;i++){
            int x=i,y=i;
            while(x<len){
                res[y][x++] = num++;
            }
            while(y<len){
                res[y++][x] = num++;
            }
            while(x>i){
                res[y][x--] = num++;
            }
            while(y>i){
                res[y--][x] = num++;
            }
            len-=1;
        }
        if(n%2==1){
            res[mid][mid]=num;
        }
        return res;
    }
}

58. 区间和(第九期模拟笔试)

题目:

给定一个整数数组 Array,请计算该数组在每个指定区间内元素的总和。

思路:

前缀和相减得中间区间

代码:

import java.util.Scanner;
public class Main {
	public static void main(String[] args) {
		Scanner s = new Scanner(System.in);
		int n = s.nextInt();
		int[] pre = new int[n+1];
		for(int i=1;i<=n;i++) {
			pre[i] = pre[i-1]+s.nextInt();
		}
		while(s.hasNextInt()) {
			int a = s.nextInt();
			int b = s.nextInt();
			System.out.println(pre[b+1]-pre[a]);
		}
	}
}


44. 开发商购买土地(第五期模拟笔试)

题目:

在一个城市区域内,被划分成了n * m个连续的区块,每个区块都拥有不同的权值,代表着其土地价值。目前,有两家开发公司,A 公司和 B 公司,希望购买这个城市区域的土地。

现在,需要将这个城市区域的所有区块分配给 A 公司和 B 公司。

然而,由于城市规划的限制,只允许将区域按横向或纵向划分成两个子区域,而且每个子区域都必须包含一个或多个区块。
为了确保公平竞争,你需要找到一种分配方式,使得 A 公司和 B 公司各自的子区域内的土地总价值之差最小。

注意:区块不可再分。

思路:

每次行/列结束统计一下切分,可以看作优化的前缀和(得到后区间,再减前区间)

代码:

import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner s = new Scanner(System.in);
		int n = s.nextInt();
		int m = s.nextInt();
		int[][] region = new int[n][m];
        int sum =0;
		for(int i=0;i<n;i++) {
			for(int j=0;j<m;j++) {
				sum+=(region[i][j] = s.nextInt());
			}
		}
        int res = Integer.MAX_VALUE;
        int tmp = 0;
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                tmp+=region[i][j];
            }
            int cur = Math.abs(sum-2*tmp);
            if(cur<res){
                res = cur;
            }
        }
        tmp = 0;
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                tmp+=region[j][i];
            }
            int cur = Math.abs(sum-2*tmp);
            if(cur<res){
                res = cur;
            }
        }
		System.out.println(res);
	}
}

卡码网周赛

227.藻类的总重量

题目:

我们用xi表示第i年年初池塘中藻类植物的总重量,那么池塘中藻类植物的发展满足这个规律xi+1 =r * xi - d。现在给你r, d, x2024,请你计算未来十年里每年年初池塘中藻类植物的总重量。

思路:

按照公式循环递推

代码:

import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner s = new Scanner(System.in);
		int r = s.nextInt();
		int d = s.nextInt();
		long x = s.nextInt();
		for(int i=0;i<10;i++) {
			x = r*x-d;
			System.out.println(x);
		}
	}
}

228.吃豆人游戏

题目:

有一款叫做吃豆人(Pacman)的游戏有许多粉丝,这些粉丝只要看到看到任何包含"pacman"作为子串的字符串就会变得非常激动。现在你有一个长度为n的字符出s,你每次可以将其中一个字母换为另外一个字母,请问你最少需要替换多少次才能使其不含有"pacman"作为子串?

思路:

统计计数每项改一个为其他未出现的字符

代码:

import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner s = new Scanner(System.in);
		String str = s.next();
		int count = 0;
		int index = 0;
		while((index = str.indexOf("pacman",index))!=-1) {
			count++;
			index+=6;
		}
		System.out.println(count);
	}
}

229.平衡子串的长度

题目:

给出一个仅由大写字母"AB"构成的字符串s,请你求出s中包含’A’和’B’个数相同的连续区间的最长长度。

思路:

和等值前缀做差即可得到符合条件的子串

代码:

import java.util.Arrays;
import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner s = new Scanner(System.in);
		int res = 0;
		String str = s.next();
		int l = str.length();
		int pre = 0;
		int[] hash = new int[l*2+1];
		Arrays.fill(hash,-1);
		hash[l] = 0;
		
		int i = 1;
		for(char c:str.toCharArray()) {
			if(c=='A') pre++;
			else pre--;
			int x = pre+l;
			if(hash[x]!=-1) {
				int len = i-hash[x];
				res = res>len?res:len;
			}else {
				hash[x] = i;
			}
			i++;
		}
		System.out.println(res);
	}
}

总结

数组篇练习了二分,双指针,滑动窗口,前缀和
数组的题目需要谨慎的处理索引的边界条件
数组元素不能删除,只能覆盖,想要真删除需要创建新的空间依次复制保留值,效率较低

往期打卡

代码随想录算法训练营第一天

你可能感兴趣的:(代码随想录打卡,算法)