【LeetCode数据结构刷题】 数组(1)

第一天打卡 【数组】

217. 存在重复元素

题目描述:
给定一个整数数组,判断是否存在重复元素。
如果任意一值在数组中出现至少两次,函数返回 true 。如果数组中每个元素都不相同,则返回 false 。

示例 1:
输入: [1,2,3,1]
输出: true

示例 2:
输入: [1,2,3,4]
输出: false

示例 3:
输入: [1,1,1,3,3,4,3,2,4,2]
输出: true

#include <iostream>
#include <unordered_set>
#include <vector>

using namespace std;

class Solution
{
public:
    bool containsDuplicate(vector<int>& nums)
    {
        unordered_set<int> s;
        for(int item : nums)
        {
            if(s.find(item) != s.end())
            {
                return true;
            }
            s.insert(item);
        }
        return false;
    }
};


int main()
{
    int a[] = { 1,1,1,3,3,4,3,2,4,2 };
    int b[] = { 1,2,3,4,5,6,7,8,9,10 };
    vector<int> arr1(a, a+10);
    vector<int> arr2(b, b+10);
    Solution solution;
    cout << solution.containsDuplicate(arr1) << endl;
    cout << solution.containsDuplicate(arr2) << endl;
    return 0;
}
复盘(vector, set)

一、vector

1、vector 的初始化

(1) vector<int> a(10); //定义了10个整型元素的向量(尖括号中为元素类型名,它可以是任何合法的数据类型),但没有给出初值,其值是不确定的。
(2) vector<int> a(10,1); //定义了10个整型元素的向量,且给出每个元素的初值为1
(3) vector<int> a(b); //用b向量来创建a向量,整体复制性赋值
(4) vector<int> a(b.begin(),b.begin+3); //定义了a值为b中第0个到第2个(共3个)元素
(5) int b[7]={1,2,3,4,5,9,8};
    vector<int> a(b,b+7); //从数组中获得初值

2、vector对象的几个重要操作

(1)a.assign(b.begin(), b.begin()+3); //b为向量,将b的0~2个元素构成的向量赋给a
(2)a.assign(4,2); //是a只含4个元素,且每个元素为2
(3)a.back(); //返回a的最后一个元素
(4)a.front(); //返回a的第一个元素
(5)a[i]; //返回a的第i个元素,当且仅当a[i]存在2013-12-07
(6)a.clear(); //清空a中的元素
(7)a.empty(); //判断a是否为空,空则返回ture,不空则返回false
(8)a.pop_back(); //删除a向量的最后一个元素
(9)a.erase(a.begin()+1,a.begin()+3); //删除a中第1个(从第0个算起)到第2个元素,也就是说删除的元素从a.begin()+1算起(包括它)一直到a.begin()+         3(不包括它)
(10)a.push_back(5); //在a的最后一个向量后插入一个元素,其值为5
(11)a.insert(a.begin()+1,5); //在a的第1个元素(从第0个算起)的位置插入数值5,如a为1,2,3,4,插入元素后为1,5,2,3,4
(12)a.insert(a.begin()+1,3,5); //在a的第1个元素(从第0个算起)的位置插入3个数,其值都为5
(13)a.insert(a.begin()+1,b+3,b+6); //b为数组,在a的第1个元素(从第0个算起)的位置插入b的第3个元素到第5个元素(不包括b+6),如b为1,2,3,4,5,9,8         ,插入元素后为1,4,5,9,2,3,4,5,9,8
(14)a.size(); //返回a中元素的个数;
(15)a.capacity(); //返回a在内存中总共可以容纳的元素个数
(16)a.resize(10); //将a的现有元素个数调至10个,多则删,少则补,其值随机
(17)a.resize(10,2); //将a的现有元素个数调至10个,多则删,少则补,其值为2
(18)a.reserve(100); //将a的容量(capacity)扩充至100,也就是说现在测试a.capacity();的时候返回值是100.这种操作只有在需要给a添加大量数据的时候才         显得有意义,因为这将避免内存多次容量扩充操作(当a的容量不足时电脑会自动扩容,当然这必然降低性能) 
(19)a.swap(b); //b为向量,将a中的元素和b中的元素进行整体性交换
(20)a==b; //b为向量,向量的比较操作还有!=,>=,<=,>,<

二、set(集合)

unordered_set 容器,可直译为“无序 set 容器”。即 unordered_set 容器和 set 容器很像,唯一的区别就在于 set 容器会自行对存储的数据进行排序,而 unordered_set 容器不会。

1、初始化

(1)set<int> set1; //创建空的set
(2)set<int> set2(set1); //拷贝构造
(3)set<int> set3(set1.begin(), set1.end()); //使用迭代器构造
(4)set<int> set4(arr,arr+5); //使用数组作为其初值进行构造
(5)set<int> set6 {1,2,10,10}; //使用处置列表进行构造

2、成员函数

(1)begin(); //返回指向第一个元素的迭代器
(2)clear(); //清除所有元素
(3)count(); //返回某个值元素的个数
(4)empty(); //如果集合为空,返回true
(5)end(); //返回指向最后一个元素的迭代器
(6)equal_range(); //返回集合中与给定值相等的上下限的两个迭代器
(7)erase(); //删除集合中的元素
(8)find(); //返回一个指向被查找到元素的迭代器
(9)get_allocator(); //返回集合的分配器
(10)insert(); //在集合中插入元素
(11)lower_bound(); //返回指向大于(或等于)某值的第一个元素的迭代器
(12)key_comp(); //返回一个用于元素间值比较的函数
(13)max_size(); //返回集合能容纳的元素的最大限值
(14)rbegin(); //返回指向集合中最后一个元素的反向迭代器
(15)rend(); //返回指向集合中第一个元素的反向迭代器
(16)size(); //集合中元素的数目
(17)swap(); //交换两个集合变量
(18)upper_bound(); //返回大于某个值元素的迭代器
(19)value_comp(); //返回一个用于比较元素间的值的函数

53. 最大子数组和

题目描述:
给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

示例:
输入: [-2,1,-3,4,-1,2,1,-5,4]
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。

#include <iostream>
#include <vector>

using namespace std;

class Solution
{
public:
    //贪心算法
    int maxSubArray_GreedyAlgorithm(vector<int> &nums)
    {
        //类似寻找最大最小值的题目,初始值一定要定义成理论上的最小最大值
        int result = INT_MIN;
        int numsSize = int(nums.size());
        int sum = 0;
        for (int i = 0; i < numsSize; i++)
        {
            sum += nums[i];
            result = max(result, sum);
            //如果sum < 0,重新开始找子序串
            if (sum < 0)
            {
                sum = 0;
            }
        }
        return result;
    }

    //动态规划
    int maxSubArray_DynamicProgramming(vector<int> &nums)
    {
        //类似寻找最大最小值的题目,初始值一定要定义成理论上的最小最大值
        int result = INT_MIN;
        int numsSize = int(nums.size());
        //dp[i]表示nums中以nums[i]结尾的最大子序和
        vector<int> dp(numsSize);
        dp[0] = nums[0];
        result = dp[0];
        for (int i = 1; i < numsSize; i++)
        {
            dp[i] = max(dp[i - 1] + nums[i], nums[i]);
            result = max(result, dp[i]);
        }
        //因为只需要知道dp的前一项,我们用int代替一维数组
        //int dp(nums[0]);
        //result = dp;
        //for (int i = 1; i < numsSize; i++)
        //{
        //    dp = max(dp + nums[i], nums[i]);
        //    result = max(result, dp);
        //}
        return result;
    }

};


int main()
{
    int a[] = {-2,1,-3,4,-1,2,1,-5,4};
    vector<int> arr1(a, a+9);
    Solution solution;
    int res1 = solution.maxSubArray_GreedyAlgorithm(arr1);
    cout << "Greedy Algorithm: " << res1 << endl;
    int res2 = solution.maxSubArray_DynamicProgramming(arr1);
    cout << "Dynamic Programming: " << res2 << endl;
    return 0;
}
复盘(贪心算法, 动态分配)

1、贪心算法

题目只要求最优解,即获取最大的值,那么很容易会考虑到贪心算法。
顾名思义,贪心算法或贪心思想采用贪心的策略,保证每次操作都是局部最优的,从而使最后得到的结果是全局最优的。

2、动态分配

将待求解的问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值