当前位置: 首页 > article >正文

Leetcode刷题笔记13

DP35 【模板】二维前缀和

【模板】二维前缀和_牛客题霸_牛客网

解法一:暴力解法 -> 模拟

直接算区间里面的和

每次询问都要遍历数组一遍

时间复杂度:O(n*m*q)

解法二:前缀和

1. 预处理出来一个前缀和矩阵
dp[i][j]表示:从[1,1]位置到[i,j]位置,这段区间里面所有元素的和
dp[i][j] = A + B + C + D = (A + B) + (A + C) + D - A

A + B = dp[i-1][j]
A + C = dp[i][j-1]
D = arr[i][j]
A = dp[i-1][j-1]
直接遍历dp一遍就能全部得出来

2. 使用前缀和矩阵

求的是[x1,y1] ~ [x2,y2]

先算出整个区域的面积,再减去
D = A + B + C + D - (A+B) - (A+C) + A 

A + B + C + D = dp[x2][y2]

A + B = dp[x1-1][y2]

A + C = dp[x2][y1-1]

A = dp[x1-1][y1-1]

A区域

B,C

使用


时间复杂度:O(m*n) + O(q)

代码:C++

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

int main() 
{
    // 1. 读入数据
    int n = 0, m = 0, q = 0;
    cin >> n >> m >> q;

    // 因为下标是从1开始计数的,所以m和n要+1才能访问到[m][n]这个位置
    vector<vector<int>> arr(n+1, vector<int>(m+1));

    for(int i=1; i<=n; i++)
    {
        for(int j=1; j<= m; j++)
        {
            cin >> arr[i][j];
        }
    }

    // 2. 预处理前缀和矩阵,longlong防止溢出
    vector<vector<long long>> dp(n+1, vector<long long>(m+1));

    for(int i=1; i<=n; i++)
    {
        for(int j=1; j<= m; j++)
        {
            dp[i][j] = dp[i-1][j] + dp[i][j-1] + arr[i][j] - dp[i-1][j-1];
        }
    }

    // 3. 使用前缀和矩阵,一共q次,所以q--
    int x1=0, y1=0, x2=0, y2=0;
    while(q--)
    {
        cin >> x1 >> y1 >> x2 >> y2;
        cout << dp[x2][y2] - dp[x1-1][y2] - dp[x2][y1-1] + dp[x1-1][y1-1] << endl;

    }

    return 0;
}

13. 罗马数字转整数

13. 罗马数字转整数 - 力扣(LeetCode)

可以直接创建一个罗马数字的映射表然后判断情况。如果当前字符不是最后一个字符并且当前字符的数值小于下一个字符的数值,就减去当前字符,可以参考IV = 4

代码:C++

class Solution {
public:
    int romanToInt(string s) 
    {
        // 建立罗马数字到整数的映射
        unordered_map<char, int> roman_map = {
            {'I', 1},
            {'V', 5},
            {'X', 10},
            {'L', 50},
            {'C', 100},
            {'D', 500},
            {'M', 1000}
        };

        int result = 0;
        int n = s.size();

        for(int i=0; i<n; i++)
        {
            // 如果当前字符不是最后一个字符,并且当前字符表示的数值小于下一个字符表示的数值
            if(i < n-1 && roman_map[s[i]] < roman_map[s[i+1]])
            {
                // 减去当前字符表示的数值
                result -= roman_map[s[i]];
            }
            else
            {
                result += roman_map[s[i]];
            }
        }
        return result;
    }
};

28. 找出字符串中第一个匹配项的下标

28. 找出字符串中第一个匹配项的下标 - 力扣(LeetCode)

解法一:KMP算法 

构建部分匹配表并记录needle中每个位置的最长相同前缀后缀的长度。

然后匹配haystack和needle,如果不匹配可以根据部分匹配表数组直接跳到可能的匹配位置,而不必从头重新匹配。

解法二:暴力匹配

代码:C++

class Solution {
public:
    int strStr(string haystack, string needle) 
    {
        int n = haystack.size(), m = needle.size();
        // 外循环遍历 haystack 的每一个可能的起始位置 i(范围为 0 到 n - m)。
        for(int i=0; i+m <= n; i++)
        {
            bool flag = true;
            // 内循环遍历 needle 的每一个字符,检查 haystack 从 i 位置开始的子串是否与 needle 匹配。
            for(int j=0; j<m; j++)
            {
                if(haystack[i+j]!=needle[j])
                {
                    flag = false;
                    break;
                }
            }
            // 如果发现匹配子串,返回其起始位置 i
            if(flag)
            {
                return i;
            }
        }
        return -1;
    }
};

66. 加一 

66. 加一 - 力扣(LeetCode)

  • 从数组的末尾开始处理

    • 从最低位(数组最后一位)开始向前遍历。
    • 如果当前位的数字小于 9,则加 1,并直接返回结果,因为加 1 不会产生进位。
    • 如果当前位的数字是 9,将其置为 0,然后继续向前处理,因为需要向更高位进 1。
  • 处理进位

    • 如果数组中的所有元素都是 9,则遍历结束后,所有位都将变成 0。
    • 这种情况下,需要在数组的开头插入一个 1,表示最高位的进位。

代码:C++

class Solution {
public:
    vector<int> plusOne(vector<int>& digits) {
        int n = digits.size(); // 获取数组的长度
        
        // 从数组的最后一个元素开始遍历
        for (int i = n - 1; i >= 0; --i) {
            if (digits[i] < 9) { // 如果当前元素小于9
                digits[i] += 1; // 将当前元素加一
                return digits; // 直接返回结果
            }
            digits[i] = 0; // 如果当前元素等于9,将其置为0
        }
        
        // 如果所有元素都是9,则在数组的开头插入1
        digits.insert(digits.begin(), 1);
        return digits; // 返回结果
    }
};

 


http://www.kler.cn/news/368316.html

相关文章:

  • springboot-springboot官方文档架构
  • 8 个用于创建电商组件的 CSS 和 JS 代码片段
  • 【LeetCode】11.盛最多水的容器
  • IP数据报的 分片与组装技术 深度解析
  • 青少年编程与数学 02-002 Sql Server 数据库应用 15课题、备份与还原
  • 用kali入侵 DarkHole_2测试
  • 16天自制CppServer-day05
  • apply,call,bind手写
  • 关于Docker的docker engine stopped问题解决
  • Lesson11---stack
  • fileinclude
  • 【计算机网络 - 基础问题】每日 3 题(五十五)
  • Discuz 论坛开发一套传奇发布站与传奇开服表
  • Python中的递归函数是如何工作的,它有哪些应用场景?
  • JAVA高性能缓存项目
  • 基于SSM 的音乐播放系统设计与实现
  • vue3中mitt和pinia的区别和主要用途,是否有可重合的部分?
  • 防火墙和堡垒机有什么区别?
  • 解决 VScode 每次打开都是上次打开的文件问题
  • 密码学+加解密封装
  • 基于neo4j的医疗问诊系统
  • 【编程语言】Kotlin快速入门 - 高阶函数与运算符重载
  • PCL库中的算法封装详解
  • 数字IC后端实现Innovus |给各种IP子模块添加port buffer和antenna diode万能脚本
  • 视频编辑的创意工坊,使用视频剪辑软件将视频随机分割成两段并去声进行MP3音频和M3u8文件的生成,让视频制作更高效
  • OpenTelemetry 实际应用