leetcode 303

2024-03-20 13:44
文章标签 leetcode 303

本文主要是介绍leetcode 303,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

leetcode 303

题目

在这里插入图片描述

例子

在这里插入图片描述

思路

使用数组存储[0, i] 的vals 值之和, sum[i] 表示 第0个元素到第(i-1)个元素之和。

代码

class NumArray {vector<int> sum;
public:NumArray(vector<int>& nums) {int n = nums.size();sum.resize(n+1);for(int i=0; i<n; i++){sum[i+1] = sum[i] + nums[i];}}int sumRange(int left, int right) {return sum[right+1] - sum[left];}
};/*** Your NumArray object will be instantiated and called as such:* NumArray* obj = new NumArray(nums);* int param_1 = obj->sumRange(left,right);*/

介绍深拷贝和浅拷贝

深拷贝(Deep Copy)和浅拷贝(Shallow Copy)是在编程中常用的两个概念,用于描述在复制对象或数据结构时发生的不同方式。以下是它们的区别:

  1. 浅拷贝(Shallow Copy):
    浅拷贝是指将一个对象的值复制到另一个对象,但只复制对象本身,而不复制对象引用的内容。因此,新对象和原始对象引用相同的内存地址,如果原始对象中包含指向其他对象的指针或引用,浅拷贝后的对象仍然会共享这些指针或引用。这可能导致多个对象共享相同的资源,当一个对象修改资源时,会影响到其他对象。

  2. 深拷贝(Deep Copy):
    深拷贝是指将一个对象的值复制到另一个对象,同时也复制对象引用的内容。这意味着新对象和原始对象引用不同的内存地址,且它们的内容是完全独立的。深拷贝会递归地复制对象的所有内容,包括嵌套对象、指针指向的对象等。因此,即使一个对象被修改,不会影响到另一个对象。

在编程中,深拷贝通常需要额外的内存和时间开销,因为需要复制整个对象及其所有嵌套内容。而浅拷贝则更为高效,但可能会导致意外的行为,特别是在多个对象共享同一资源时。

在设计程序时,需要根据需求和情况选择适合的拷贝方式。如果需要独立的对象副本,应该使用深拷贝;如果只是需要共享数据,可以使用浅拷贝。在C++中,通过重载拷贝构造函数和赋值运算符可以实现深拷贝。

浅拷贝和深拷贝的区分:

  1. 内存管理:浅拷贝只是简单地复制指针,使得新对象和原对象共享同一块内存空间,而深拷贝会为新对象分配新的内存空间,并将原对象的数据复制到新的内存空间中。

  2. 析构函数:深拷贝通常会定义自己的析构函数来释放动态分配的内存,确保在对象被销毁时内存得到正确释放,而浅拷贝可能会导致内存泄漏或悬挂指针的问题。

  3. 拷贝构造函数:深拷贝会在拷贝构造函数中进行数据的深度复制,而浅拷贝只是简单地复制指针,导致新旧对象共享同一内存地址。

  4. 赋值运算符重载:深拷贝通常会重载赋值运算符 =,以确保在对象赋值时进行深度复制,而浅拷贝可能会导致赋值后的对象共享数据。

  5. 数据的独立性:通过修改一个对象的数据,观察另一个对象的数据是否受影响,如果受影响则是浅拷贝,如果不受影响则是深拷贝。

浅拷贝例子

以下是一个简单的示例,展示了浅拷贝的概念和效果:

#include <iostream>
#include <vector>using namespace std;class MyClass {
public:int* data;// 构造函数MyClass(int value) {data = new int(value);}// 拷贝构造函数(浅拷贝)MyClass(const MyClass& other) {data = other.data; // 浅拷贝,共享同一内存地址}// 析构函数~MyClass() {delete data;}
};int main() {// 创建对象 aMyClass a(5);// 浅拷贝对象 a 到对象 bMyClass b = a;// 修改对象 b 的值*(b.data) = 10;// 输出对象 a 和对象 b 的值cout << "a.data: " << *(a.data) << endl; // 输出 10,因为对象 a 和对象 b 共享同一内存地址cout << "b.data: " << *(b.data) << endl; // 输出 10return 0;
}

在上面的示例中,我们定义了一个名为 MyClass 的类,其中包含一个指向整数的指针 data。在拷贝构造函数中,我们进行了浅拷贝,即将对象 otherdata 指针赋值给当前对象的 data 指针,导致两个对象共享同一内存地址。

main 函数中,我们创建了对象 a,然后通过浅拷贝将其复制到对象 b。当我们修改对象 b 的值时,对象 a 的值也被修改,因为它们共享同一内存地址。这就是浅拷贝的效果,可能导致意外的行为和数据共享问题。

深拷贝

以下是一个简单的示例,展示了深拷贝的概念和效果:

#include <iostream>class MyArray {
private:int size;int* data;public:// 构造函数MyArray(int s) : size(s), data(new int[s]) {}// 拷贝构造函数(深拷贝)MyArray(const MyArray& other) : size(other.size), data(new int[other.size]) {for (int i = 0; i < size; i++) {data[i] = other.data[i];}}// 析构函数~MyArray() {delete[] data;}// 打印数组元素void print() {for (int i = 0; i < size; i++) {std::cout << data[i] << " ";}std::cout << std::endl;}
};int main() {// 创建对象 aMyArray a(5);for (int i = 0; i < 5; i++) {a.data[i] = i + 1;}// 深拷贝对象 a 到对象 bMyArray b = a;// 修改对象 b 的值b.data[0] = 10;// 输出对象 a 和对象 b 的值std::cout << "a: ";a.print(); // 输出 1 2 3 4 5std::cout << "b: ";b.print(); // 输出 10 2 3 4 5return 0;
}

在上面的示例中,我们定义了一个名为 MyArray 的类,其中包含一个整数大小和一个指向整数数组的指针 data。在拷贝构造函数中,我们进行了深拷贝,即为新对象分配了新的内存空间,并将原对象的数据复制到新的内存空间中,从而避免了数据共享问题。

main 函数中,我们创建了对象 a,并为其数组赋值。然后通过深拷贝将对象 a 复制到对象 b。当我们修改对象 b 的值时,对象 a 的值不会受到影响,因为它们拥有各自独立的内存空间。

这篇关于leetcode 303的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/829626

相关文章

哈希leetcode-1

目录 1前言 2.例题  2.1两数之和 2.2判断是否互为字符重排 2.3存在重复元素1 2.4存在重复元素2 2.5字母异位词分组 1前言 哈希表主要是适合于快速查找某个元素(O(1)) 当我们要频繁的查找某个元素,第一哈希表O(1),第二,二分O(log n) 一般可以分为语言自带的容器哈希和用数组模拟的简易哈希。 最简单的比如数组模拟字符存储,只要开26个c

leetcode-24Swap Nodes in Pairs

带头结点。 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) { val = x; }* }*/public class Solution {public ListNode swapPairs(L

leetcode-23Merge k Sorted Lists

带头结点。 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) { val = x; }* }*/public class Solution {public ListNode mergeKLists

C++ | Leetcode C++题解之第393题UTF-8编码验证

题目: 题解: class Solution {public:static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num &

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟)

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟) 题目描述 给定一个链表,链表中的每个节点代表一个整数。链表中的整数由 0 分隔开,表示不同的区间。链表的开始和结束节点的值都为 0。任务是将每两个相邻的 0 之间的所有节点合并成一个节点,新节点的值为原区间内所有节点值的和。合并后,需要移除所有的 0,并返回修改后的链表头节点。 思路分析 初始化:创建一个虚拟头节点

C语言 | Leetcode C语言题解之第393题UTF-8编码验证

题目: 题解: static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num & MASK1) == 0) {return

【JavaScript】LeetCode:16-20

文章目录 16 无重复字符的最长字串17 找到字符串中所有字母异位词18 和为K的子数组19 滑动窗口最大值20 最小覆盖字串 16 无重复字符的最长字串 滑动窗口 + 哈希表这里用哈希集合Set()实现。左指针i,右指针j,从头遍历数组,若j指针指向的元素不在set中,则加入该元素,否则更新结果res,删除集合中i指针指向的元素,进入下一轮循环。 /*** @param

LeetCode:64. 最大正方形 动态规划 时间复杂度O(nm)

64. 最大正方形 题目链接 题目描述 给定一个由 0 和 1 组成的二维矩阵,找出只包含 1 的最大正方形,并返回其面积。 示例1: 输入: 1 0 1 0 01 0 1 1 11 1 1 1 11 0 0 1 0输出: 4 示例2: 输入: 0 1 1 0 01 1 1 1 11 1 1 1 11 1 1 1 1输出: 9 解题思路 这道题的思路是使用动态规划

LeetCode 第414场周赛个人题解

目录 Q1. 将日期转换为二进制表示 原题链接 思路分析 AC代码 Q2. 范围内整数的最大得分 原题链接 思路分析 AC代码 Q3. 到达数组末尾的最大得分 原题链接 思路分析 AC代码 Q4. 吃掉所有兵需要的最多移动次数 原题链接 思路分析 AC代码 Q1. 将日期转换为二进制表示 原题链接 Q1. 将日期转换为二进制表示 思路分析

【JavaScript】LeetCode:21-25

文章目录 21 最大子数组和22 合并区间23 轮转数组24 除自身以外数组的乘积25 缺失的第一个正数 21 最大子数组和 贪心 / 动态规划贪心:连续和(count)< 0时,放弃当前起点的连续和,将下一个数作为新起点,这里提供使用贪心算法解决本题的代码。动态规划:dp[i]:以nums[i]为结尾的最长连续子序列(子数组)和。 dp[i] = max(dp[i - 1]