首页 > 编程语言 >代码随想录算法训练营第二天| 209.长度最小的子数组、59.螺旋矩阵II 、区间和、开发商购买土地

代码随想录算法训练营第二天| 209.长度最小的子数组、59.螺旋矩阵II 、区间和、开发商购买土地

时间:2024-09-28 11:01:54浏览次数:5  
标签:count 59 nums 209 res 随想录 int vector vec

209.长度最小的子数组

此题注重理解,同时我将res一开始初始化为sums的长度加一(因为不可能为此长度)
INT32_MAX 是一个常量,代表 32 位有符号整数的最大值

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int i=0,j=0;//i为起始位置,j为终止位置
        int sum=0;//当前子数列总和
        int sublen=0;//当前子数列长度
        int res=nums.size()+1;//不可能超过这个,或int res = INT32_MAX;
        for(j;j<nums.size();j++){//循环遍历指导大于等于target
            sum+=nums[j];
            while(sum>=target){//一旦加上新的nums[j]使得sum符合条件,则开始动态调整i
                sublen=j-i+1;
                res=res>sublen?sublen:res;//看看当前是否需要更新最小值
                sum=sum-nums[i];//从这里开始是预判下一个
                i++;
            }
        }
        return res==nums.size()+1?0:res;
    }
};

python中直接有min()函数,避免进行比较再取值:
float('inf')inf表示infinite

class Solution(object):
    def minSubArrayLen(self, target, nums):
        """
        :type target: int
        :type nums: List[int]
        :rtype: int
        """
        i,j=0,0#起始和终止
        sum=0
        res=len(nums)+1#不可能的长度,或者可以res = float('inf')
        sublen=0#子长度
        while j<len(nums):
            sum=sum+nums[j]
            while sum>=target:
                sublen=j-i+1
                res=min(res,sublen)#更新
                sum=sum-nums[i]
                i=i+1
            j=j+1
        if res==len(nums)+1:
            return 0
        else:
            return res

59.螺旋矩阵II

class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {
        int startx=0;
        int starty=0;
        int count=1;
        int i=0,j=0;
        int loop=n/2;
        int offset=1;
        vector<vector<int>> res(n,vector<int>(n,0));//二维vector,括号内第一个参数是row数,第二个参数是每行有多少个,初始化为什么(此处为0)
        while(loop-->0){
            for(j=starty;j<n-offset;j++){
                res[startx][j]=count++;
            }
            for(i=startx;i<n-offset;i++){
                res[i][j]=count++;
            }
            for(;j>starty;j--){
                res[i][j]=count++;
            }
            for(;i>startx;i--){
                res[i][j]=count++;
            }
            startx++;
            starty++;
            offset++;
        }
        if(n%2==1){
            res[n/2][n/2]=count;
        }
        return res;
    }
};
var generateMatrix = function(n) {
    let i=0,j=0;
    let startx=0,starty=0;
    let count=1;
    let loop=parseInt(n/2);
    let mid=parseInt(n/2);
    let offset=1;
    let res=new Array(n).fill(0).map(()=>new Array(n).fill(0));//js创建数组还是不熟悉
    //map的作用是调用回调函数
    while(loop-- >0){
        for(j=starty;j<n-offset;j++){
            res[startx][j]=count++;
        }
        for(i=startx;i<n-offset;i++){
            res[i][j]=count++;
        }
        for(;j>starty;j--){
            res[i][j]=count++;
        }
        for(;i>startx;i--){
            res[i][j]=count++;
        }
        startx++;
        starty++;
        offset++;//自己写的时候这个漏了
    }
    if(n%2==1){
        res[mid][mid]=count;
    }
    return res;
};
class Solution(object):
    def generateMatrix(self, n):
        """
        :type n: int
        :rtype: List[List[int]]
        """
        startx,starty=0,0
        count=1
        loop,mid=n//2,n//2 #注意这里是//
        nums = [[0] * n for _ in range(n)]  #学会这里的构造二维数组!
        #通过列表推导式,在每次循环中生成一个长度为 n 的列表 [0, 0, 0, ..., 0],一共生成 n 行,最终形成一个 n x n 的二维矩阵。
        for offset in range(1,loop+1):  #python中可以用for in结构
            for j in range(starty,n-offset): #range(start, stop, step),
                nums[startx][j]=count
                count=count+1
            for i in range(startx,n-offset):
                nums[i][n-offset]=count  #和C++里的逻辑不一样,j无固定值,不可写成nums[i][j]=count
                count+=1
            #start(可选):序列的起始位置。默认是 0。
            #stop:序列的结束位置(不包括 stop 本身)。
            #step(可选):序列中数字的增量,默认为 1。可以是正数或负数。
            for j in range(n-offset,starty,-1):
                nums[n-offset][j]=count
                count+=1
            for i in range(n-offset,startx,-1):
                nums[i][startx]=count
                count+=1
            startx+=1
            starty+=1
        if n%2==1:
            nums[mid][mid]=count
        return nums

区间和

采用暴力解法会超时,来举一个极端的例子,如果查询m次,每次查询的范围都是从0 到 n - 1。
那么该算法的时间复杂度是 O(n * m) m 是查询的次数,如果查询次数非常大的话,这个时间复杂度也是非常大的。

引入前缀和
前缀和 在涉及计算区间和的问题时非常有用!

#include <iostream>
#include <vector>
using namespace std;

int main(){
    int n,a,b;
    cin>>n;
    vector<int> vec(n);
    vector<int> p(n);//前缀和
    int sump=0;
    for(int i=0;i<n;i++){
        cin>>vec[i];
        sump+=vec[i];
        p[i]=sump;
    }
    while(cin>>a>>b){
        cout<<p[b]-p[a-1]<<endl;
    }
    return 0;
}

注意这样不会每次都遍历计算区间,只需要将前缀进行相减即可

#python
import sys

input = sys.stdin.read

def main():
    data = input().split()
    n = int(data[0])  # 第一个数是数组的大小
    vec = []
    p = [0] * n  # 前缀和数组
    sump = 0

    # 构建 vec 和前缀和数组 p
    for i in range(n):
        vec.append(int(data[i + 1]))
        sump += vec[i]
        p[i] = sump
    
    index = n + 1  # 跳过前面 n 个数字

    # 处理查询部分
    while index < len(data):
        a = int(data[index])
        b = int(data[index + 1])
        index += 2
        
        if a == 0:
            print(p[b])
        else:
            print(p[b] - p[a - 1])

if __name__ == "__main__":
    main()

对于上述的数组,如果一开始没有为数组赋值,则不能直接操作vec[i],否则会报错index out of range
此时应使用append()函数来向数组的末尾进行增加

vec=[]
vec.append(int(data[i + 1]))

或者在一开始就对数组进行初始化,确定其长度和具体的值

vec = [0] * n  # 创建一个大小为 n 的列表,初始值为 0
vec[i] = int(data[i + 1])

开发商购买土地

#include <iostream>
#include <vector>
#include <climits>
using namespace std;

int main(){
    int n,m;
    cin>>n>>m;
    int sum=0;
    //为所有土地赋值,并计算所有土地的和
    vector<vector<int>> field(n,vector<int>(m,0));
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            cin>>field[i][j];
            sum+=field[i][j];
        }
    }
    
    //计算前i行土地总和
    vector<int> horizental(n,0);
    vector<int> horizentalCut(n,0);
    int sumH;
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            horizental[i]+=field[i][j];
        }
        sumH+=horizental[i];//这里一开始写成了horizentalCut[i]+=horizental[i];其实并没有起到累加的作用
        horizentalCut[i]=sumH;
    }
    
    //计算前j列土地的总和
    vector<int> vertical(m,0);
    vector<int> verticalCut(m,0);
    int sumV;
    for(int j=0;j<m;j++){
        for(int i=0;i<n;i++){
            vertical[j]+=field[i][j];
        }
        sumV+=vertical[j];
        verticalCut[j]=sumV;
    }
    
    int res=INT_MAX;
    //比较横向的分割最小值
    for(int i=0;i<n-1;i++){
        res=min(res,abs(sum-horizentalCut[i]-horizentalCut[i]));
    }
    //比较纵向的分割最小值
    for(int j=0;j<m-1;j++){
        res=min(res,abs(sum-verticalCut[j]-verticalCut[j]));
    }
    cout<<res<<endl;
}

一开始写的时候没有使得前i行(或前j列)土地和起到累加的作用

标签:count,59,nums,209,res,随想录,int,vector,vec
From: https://www.cnblogs.com/VickyWu/p/18435918

相关文章

  • 代码随想录训练营第44天|最长公共子序列
    1143.最长公共子序列classSolution{public:intlongestCommonSubsequence(stringtext1,stringtext2){text1.insert(text1.begin(),'');text2.insert(text2.begin(),'');intn1=text1.length(),n2=text2.length(),m......
  • P2090 数字对
    P2090数字对不是,这不是黄题吗,鉴定为我太菜了考虑这东西长得像辗转相除法。最终结果一定是\((n,B)\)这样子的。那么它一定是由\((n-B,B)\)转移过来。对于\((a,b)\)如果\(a>b\)它会变成\((a-b,b)\),否则是\((a,b-a)\)。于是也许我们可以枚举\(B\),把\(a-b\)这个操作......
  • CF1592F2-Alice and Recoloring 2-分析、二分图
    link:https://codeforces.com/contest/1592/problem/F2题意:给定一个\(n\)行\(m\)列的目标矩阵,矩阵元素只有W或B,并且你有一个初始矩阵,元素全为W。现在你可以矩阵实施以下操作:使用一块钱,选定一个包含\((1,1)\)的子矩阵,把矩阵中的元素全部反转(W变B,B变W)。使用......
  • 代码随想录算法训练营第一天| 704. 二分查找、27. 移除元素、977.有序数组的平方。
    704.二分查找总结:防止int溢出:classSolution{public:intsearch(vector<int>&nums,inttarget){intleft=0;intright=nums.size()-1;while(left<=right){intmiddle=(left+right)/2;//intmid=(right-left)/......
  • 题解:P10590 磁力块
    \(\text{Link}\)来自传奇讨论区大神@年年有年的\(O(n\logn)\)做法!题意有\(n+1\)块磁铁\(0\simn\),每个磁铁都有四个属性\((d_i,m_i,p_i,r_i)\),如果你拥有了磁铁\(i\),那么你就能吸引并拥有所有满足\(d_j\ler_i,m_j\lep_i\)的磁铁\(j\),初始你只拥有磁铁\(0\),求最......
  • 74hc595
    74htc595功能8位串行输入8位串行或并行输出带3态输出的存储寄存器带直接清零的移位寄存器100MHZ(典型)移出频率ESD保护HBMELAJESD22-A114-A超过2000VMMEIAJESD23-A115-A超过200V 说明74HC/HCT595是高速硅栅CMOS器件,与低功率肖特基TTLLSTTL引脚兼容。它们是根据JE......
  • Codeforces Round 959 (Div. 1 + Div. 2) C. Hungry Games题解
    CodeforcesRound959(Div.1+Div.2)C.HungryGames题解题目链接大致题意:给定一个长度为n的数组,并且给出一对l,r表示一个区间,如果∑i......
  • 【代码随想录Day27】贪心算法Part01
    理论基础题目链接/文章讲解:代码随想录视频讲解:贪心算法理论基础!_哔哩哔哩_bilibili455.分发饼干题目链接/文章讲解:代码随想录视频讲解:贪心算法,你想先喂哪个小孩?|LeetCode:455.分发饼干_哔哩哔哩_bilibili一开始使用了双重循环,时间复杂度为......
  • 【代码随想录Day25】回溯算法Part04
    491.递增子序列题目链接/文章讲解:代码随想录视频讲解:回溯算法精讲,树层去重与树枝去重|LeetCode:491.递增子序列_哔哩哔哩_bilibiliclassSolution{List<List<Integer>>result=newArrayList<>();LinkedList<Integer>path=newLinkedList<>();pub......
  • 591从机库ota
    一.IAP修改点:1:LD文件修改起始地址为0,长度为8k,2:启动文件修改指向地址为库的起始地址48k,即0xC000。3:ota.h中修改各部分起始地址和大小,4.预编译宏中添加库起始地址,5.添加新的mcu.c文件,屏蔽校准函数,目的是节省flash空间。 二:app需修改处:1.LD文件2.启动文件3.预编译......