力扣数据结构刷题Day1-4

文章目录

  • 力扣数据结构刷题Day1-4
  • 前言
  • 一、小试牛刀
    • 存在重复元素(L217)
    • 最大子数组和(L53)
      • 动态规划法
      • 贪心法
      • 分治法
    • 两数之和(L1)
    • 合并两个有序数组 (L88)
    • 买卖股票的最佳时机(L121)
    • 两个数组的交集(L350)
      • 使用哈希表
      • 排序+双指针
    • 重塑矩阵(L566)
    • 杨辉三角(L118)
  • 总结

前言

小小记录下数据结构的学习过程(花了365开极速判题通道 小小哭个穷呜呜呜)


一、小试牛刀

存在重复元素(L217)

给你一个整数数组 nums 。如果任一值在数组中出现 至少两次 ,返回 true ;如果数组中每个元素互不相同,返回 false 。

bool containsDuplicate(vector<int>&nums){int len=nums.size();sort(nums.begin(),nums.end());for(int i=0;i<len-1;++i){if(nums[i]==nums[i+1]){return true;}}return false;
}

最大子数组和(L53)

给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

子数组 是数组中的一个连续部分。

动态规划法

int maxSubArray(vector<int>& nums) {int a=nums[0],b=0;for(int i=0;i<nums.size();i++){b=fmax(nums[i]+b,nums[i]);a=fmax(a,b);}return a;}

设f(i)为第i个数结尾的连续子数组的最大和
动态规划转移方程:f(i) = max{f(i-1)+nums[i],nums[i]}

贪心法

    int sum=0;for(int i=0;i<numsSize;i++){sum+=nums[i];result=max(result,sum);if(sum<0) sum=0;}return result;

分治法

int maxSubArray(vector<int> &nums){//类似寻找最大最小值的题目,初始值一定要定义成理论上的最小最大值int result = INT_MIN;int numsSize = int(nums.size());result = maxSubArrayHelper(nums, 0, numsSize - 1);return result;}int maxSubArrayHelper(vector<int> &nums, int left, int right){if (left == right){return nums[left];}int mid = (left + right) / 2;int leftSum = maxSubArrayHelper(nums, left, mid);//注意这里应是mid + 1,否则left + 1 = right时,会无线循环int rightSum = maxSubArrayHelper(nums, mid + 1, right);int midSum = findMaxCrossingSubarray(nums, left, mid, right);int result = max(leftSum, rightSum);result = max(result, midSum);return result;}int findMaxCrossingSubarray(vector<int> &nums, int left, int mid, int right){int leftSum = INT_MIN;int sum = 0;for (int i = mid; i >= left; i--){sum += nums[i];leftSum = max(leftSum, sum);}int rightSum = INT_MIN;sum = 0;//注意这里i = mid + 1,避免重复用到nums[i]for (int i = mid + 1; i <= right; i++){sum += nums[i];rightSum = max(rightSum, sum);}return (leftSum + rightSum);}作者:pinku-2
链接:https://leetcode-cn.com/problems/maximum-subarray/solution/zui-da-zi-xu-he-cshi-xian-si-chong-jie-fa-bao-li-f/
来源:力扣(LeetCode)

两数之和(L1)

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。

你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。

vector<int> twoSum(vector<int>& nums, int target) {int n=nums.size();int i,j;for(i=0;i<n-1;i++){for(j=i+1;j<n;j++){if(nums[i]+nums[j]==target){return {i,j};}}}return {};}

或使用哈希表如下

vector<int> twoSum(vector<int>& nums, int target) {unordered_map<int, int> hashtable;for (int i = 0; i < nums.size(); ++i) {auto it = hashtable.find(target - nums[i]);if (it != hashtable.end()) {return {it->second, i};}hashtable[nums[i]] = i;}return {};}
作者:LeetCode-Solution

合并两个有序数组 (L88)

给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。

请你 合并 nums2 到 nums1 中,使合并后的数组同样按 非递减顺序 排列。

注意:最终,合并后数组不应由函数返回,而是存储在数组 nums1 中。为了应对这种情况,nums1 的初始长度为 m + n,其中前 m 个元素表示应合并的元素,后 n 个元素为 0 ,应忽略。nums2 的长度为 n 。

双指针easy
以下代码使用逆向双指针

void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {int p1 = m - 1, p2 = n - 1;int tail = m + n - 1;int cur;while (p1 >= 0 || p2 >= 0) {if (p1 == -1) {cur = nums2[p2--];} else if (p2 == -1) {cur = nums1[p1--];} else if (nums1[p1] > nums2[p2]) {cur = nums1[p1--];} else {cur = nums2[p2--];}nums1[tail--] = cur;}}作者:LeetCode-Solution

买卖股票的最佳时机(L121)

给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。

你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。

返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回 0 。

最重要的是要想到用二维数组!

int maxProfit(vector<int>& prices) {int len=prices.size();if(len<2) return 0;int dp[len][2];dp[0][0]=0;dp[0][1]=-prices[0];for(int i=1;i<len;i++){dp[i][0]=max(dp[i-1][1]+prices[i],dp[i-1][0]);dp[i][1]=max(-prices[i],dp[i-1][1]);}return dp[len-1][0];}

两个数组的交集(L350)

给你两个整数数组 nums1 和 nums2 ,请你以数组形式返回两数组的交集。返回结果中每个元素出现的次数,应与元素在两个数组中都出现的次数一致(如果出现次数不一致,则考虑取较小值)。
可以不考虑输出结果的顺序。

使用哈希表

vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {if (nums1.size() > nums2.size()) {return intersect(nums2, nums1);}unordered_map <int, int> m;for (int num : nums1) {++m[num];}vector<int> intersection;for (int num : nums2) {if (m.count(num)) {intersection.push_back(num);--m[num];if (m[num] == 0) {m.erase(num);}}}return intersection;}作者:LeetCode-Solution

排序+双指针

(方便之处在于有一个数组被便利完后可直接结束)

vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {sort(nums1.begin(), nums1.end());sort(nums2.begin(), nums2.end());int length1 = nums1.size(), length2 = nums2.size();vector<int> intersection;int index1 = 0, index2 = 0;while (index1 < length1 && index2 < length2) {if (nums1[index1] < nums2[index2]) {index1++;} else if (nums1[index1] > nums2[index2]) {index2++;} else {intersection.push_back(nums1[index1]);index1++;index2++;}}return intersection;}
作者:LeetCode-Solution

重塑矩阵(L566)

在 MATLAB 中,有一个非常有用的函数 reshape ,它可以将一个 m x n 矩阵重塑为另一个大小不同(r x c)的新矩阵,但保留其原始数据。

给你一个由二维数组 mat 表示的 m x n 矩阵,以及两个正整数 r 和 c ,分别表示想要的重构的矩阵的行数和列数。

重构后的矩阵需要将原始矩阵的所有元素以相同的 行遍历顺序 填充。

如果具有给定参数的 reshape 操作是可行且合理的,则输出新的重塑矩阵;否则,输出原始矩阵。

将二维数组用一维形式遍历;构建的二维数组录入时行数和列数运用当前数的序数与列数的商和余数。

vector<vector<int>> matrixReshape(vector<vector<int>>& mat, int r, int c) {int m=mat.size();int n=mat[0].size();if(r*c!=m*n){return mat;}vector<vector<int>> ans(r,vector<int>(c));for(int i=0;i<m*n;++i){ans[i/c][i%c]=mat[i/n][i%n];}return ans;}

杨辉三角(L118)

堪称最简单的动态规划了。
重点是用resize保证输出的每一行的容量变化!

vector<vector<int>> generate(int numRows) {vector<vector<int>> dp(numRows);for(int i=0;i<numRows;++i){dp[i].resize(i+1);dp[i][0]=1;dp[i][i]=1;}for(int a=2;a<numRows;++a){for(int b=1;b<a;++b){dp[a][b]=dp[a-1][b-1]+dp[a-1][b];}}return dp;}

总结

第一篇over!求三连,求评论啦啦啦!!!

力扣数据结构刷题Day1-4相关推荐

  1. Leetcode-How-What 力扣Leetcode刷题指南

    Leetcode-How-What 力扣Leetcode刷题指南 About the way how to use Leetcode wisely for preparing the intervie ...

  2. 力扣(LeetCode)刷题,简单+中等题(第35期)

    力扣(LeetCode)定期刷题,每期10道题,业务繁重的同志可以看看我分享的思路,不是最高效解决方案,只求互相提升. 第1题:解码异或后的排列 试题要求如下: 回答(C语言): /*** Note: ...

  3. 力扣(LeetCode)刷题,简单+中等题(第34期)

    目录 第1题:整数转罗马数字 第2题:电话号码的字母组合 第3题:二叉树的所有路径 第4题:砖墙 第5题:下一个排列 第6题:括号生成 第7题:删除并获得点数 第8题:全排列 第9题:颜色分类 第10 ...

  4. 力扣(LeetCode)刷题,简单+中等题(第33期)

    目录 第1题:Z 字形变换 第2题:删除字符串中的所有相邻重复项 第3题:基本计算器 II 第4题:螺旋矩阵 第5题:螺旋矩阵 II 第6题:盛最多水的容器 第7题:删除有序数组中的重复项 II 第8 ...

  5. 力扣(LeetCode)刷题,简单+中等题(第32期)

    目录 第1题:数组的度 第2题:托普利茨矩阵 第3题:爱生气的书店老板 第4题:翻转图像 第5题:有效的数独 第6题:无重复字符的最长子串 第7题:区域和检索 - 数组不可变 第8题:二维区域和检索 ...

  6. 力扣(LeetCode)刷题,简单+中等题(第31期)

    目录 第1题:同构字符串 第2题:最后一块石头的重量 第3题:最小路径和 第4题:键盘行 第5题:存在重复元素 II 第6题:两数相加 第7题:三个数的最大乘积 第8题:等价多米诺骨牌对的数量 第9题 ...

  7. 力扣(LeetCode)刷题,简单+中等题(第30期)

    目录 第1题:单词规律 第2题:找不同 第3题:在排序数组中查找元素的第一个和最后一个位置 第4题:使用最小花费爬楼梯 第5题:寻找峰值 第6题:字符串中的第一个唯一字符 第7题:两个数组的交集 II ...

  8. 力扣(LeetCode)刷题,简单+中等题(第29期)

    目录 第1题:分割数组为连续子序列 第2题:翻转矩阵后的得分 第3题:寻找旋转排序数组中的最小值 第4题:乘积最大子数组 第5题:不同路径 第6题:判断路径是否相交 第7题:摆动序列 第8题:单调递增 ...

  9. 力扣(LeetCode)刷题,简单+中等题(第28期)

    目录 第1题:翻转单词顺序 第2题:顺时针打印矩阵 第3题:总持续时间可被 60 整除的歌曲 第4题:字符串的最大公因子 第5题:上升下降字符串 第6题:将数组分成和相等的三个部分 第7题:可被 5 ...

最新文章

  1. 为了智能驾驶,李彦宏要改造城市道路
  2. 最最最全面的Java异常面试及解答
  3. Win10一周更新系统开始面向企业分支推送
  4. 《敏捷迭代开发:管理者指南》—第2章2.9节增量交付
  5. 卡片游戏 数学期望
  6. Django学习笔记(4)
  7. 聊聊近期的感受和10月文章精选!
  8. Ubuntu 安装MySQL报共享库找不到
  9. createprocess 系统找不到指定的文件_告别文件混乱和找不到,文件管理的新思路...
  10. javascript call 详细解答与实践
  11. [渝粤教育] 平顶山学院 区域分析与规划 参考 资料
  12. win2008服务器系统玩红警,如何让Win8顺利兼容红警2
  13. 用scratch2.0编飞机大战
  14. 怎么安装消息队列服务器,安装和配置消息队列(针对存档服务器)
  15. display: flex自我理解
  16. 小样本算法库LibFewShot
  17. 编译原理-递归子程序法
  18. Excel如何隔行插入图片?
  19. 微服务体系中的分层设计和领域划分!
  20. 【正点原子I.MX6U-MINI应用篇】6、嵌入式Linux在LCD屏幕上显示字符

热门文章

  1. 华为 微信视频 连接到服务器,华为EMUI10里这个新功能,想要干掉微信视频?
  2. WordPress社区论坛管理工具,WordPress社区论坛发帖工具
  3. 基于ALSA实现代码调节音量
  4. “0x00446d22”指令引用的“0xcccd40d5”内存。该内存不能为read。
  5. nonebot2插件——百度贴吧攻略插件
  6. 如何警惕网络钓鱼新花样—“刷钻、刷信用”
  7. 基于Matplotlib的五边形雷达图
  8. 技术盛宴SD2.0大会隆重开幕,现场图文直播,敬请关注!
  9. 微信小程序填坑之路(六):wx.getUserInfo 接口的变动与使用
  10. Android测试游戏帧数的方法