53.最大子序和【easy】
给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
示例1
输入:nums = [-2,1,-3,4,-1,2,1,-5,4]
输出:6
解释:连续子数组 [4,-1,2,1] 的和最大,为 6
简单题(并不)。这是一道动态规划,借鉴了大佬的思路。
题目理解:
1,如果全是负数或零,取最大的一个数 ;
2,排除第一种情况,最大子序中的第一个数一定是正数。
3,从某个数开始计算sum,直至sum为0,再清空子序重新计算sum,留下所有求和过程中sum的最大值(用ans表示)。
算法理解:
使用sum计算从某个数开始的子序合,用ans保存sum达到过的最大值。
sum只管从i往后加,sum<0时就清空sum重新换,ans保存sum的最大值。
这里是引用
int maxdata(vector<int>& nums)
{
int i=0;
int sum=0;
int ans=nums[0];
for(i=0;i<nums.size();i++)
{
sum = sum + nums[i];
ans = max(sum,ans);
if(sum<0)
{
sum=0;
}
}
return ans;
}
1.两数之和【easy】
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。 你可以按任意顺序返回答案。
题解:
这个题使用了hashmap,思路如下:
遍历数组,读数字 i :
1,查看hashmap中是否有key=nums[i]对应的value;
2,如果有,就返回key=nums[i]对应的value 以及 i;
如果没有,就把hashmap中存入key=target-nums[i]的value i;
例如nums = [3,2,4], target = 6
1,遍历数字nums[0] = 3
2,查hashmap[3],没找到
,3,将hashmap[9-3] = hashmap[6] =0 存入,如果后面遍历到了数字6,那么就说明6和数组下标为0的数字可以组成target;
值得一提的是,我发现hashmap在赋值的时候默认value等于0,在储存的时候会和下标0混淆,所以我在储存下标的时候使用了“下标+1”,在return的时候再把“1”减掉。
hashmap的使用方法
#include <map> //导入包
map<int,int> Inthash; //声明,int-int可以替换成其他数据类型
Inthash[1]=i+1; //赋值
vector使用方法
#include <vector>
vector<int> nums; //声明
nums.push_back(val); //在vector最后添加数据
nums.pop_back() //从最后删除数据
nums.size() //返回vector大小
怎么在vector的内部删除某一下标i的元素,??
上代码
vector<int> twoSum(vector<int>& nums, int target)
{
vector<int> anser;
map<int,int> Inthash;
for(int i=0;i<nums.size();i++)
{
if(Inthash[nums[i]])
{
anser.push_back(Inthash[nums[i]]-1);
anser.push_back(i);
return anser;
}
else
{
Inthash[target-nums[i]]=i+1;
}
}
}
88.合并两个有序数组【easy】
给你两个有序整数数组 nums1 和 nums2,请你将 nums2 合并到 nums1 中,使 nums1 成为一个有序数组。
初始化 nums1 和 nums2 的元素数量分别为 m 和 n 。你可以假设 nums1 的空间大小等于 m + n,这样它就有足够的空间保存来自 nums2 的元素。
这个题比较简单,我最开始的方法是用空间换时间,先把nums1和nums2在vector temp中排好序,再把temp赋给nums1.
//空间换时间
void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
vector<int> temp;
int i=0,j=0;
while(i<m && j<n)
{
if(nums1[i]<nums2[j])
{
temp.push_back(nums1[i]);
i++;
}
else
{
temp.push_back(nums2[j]);
j++;
}
}
while(i<m)
{
temp.push_back(nums1[i]);
i++;
}
while(j<n)
{
temp.push_back(nums2[j]);
j++;
}
nums1.clear();
nums1 = temp;
}
另外学习了一个不需要辅助空间的方法。因为nums1的长度刚好等于m+n,nums1中有m和数,nums2有n个数,也就是说合并好的数组的长度是固定的(不删除相同元素),因此可以从最后遍历。
//不换
void merge2(vector<int>& nums1, int m, vector<int>& nums2, int n)
{
int i=m-1,j=n-1;
int k=m+n-1;
while(i>=0 && j>=0)
{
if(nums1[i]>nums2[j])
{
nums1[k] = nums1[i];
k--;
i--;
}
else
{
nums1[k] = nums2[j];
k--;
j--;
}
}
while(i>=0)
{
nums1[k] = nums1[i];
k--;
i--;
}
while(j>=0)
{
nums1[k] = nums2[j];
k--;
j--;
}
}
350. 两个数组的交集 II 【easy】
这个题最先想到的办法就是空间换时间,用hashmap做。时间复杂度O(m+n)。
首先遍历第一个数组,把他们放进对应的hashmap中,每出现一次就加一,记录每个数字出现的个数。
然后遍历第二个数组,每遍历一个数字就查询一下hashmap中的记录(是否有这个数),有的话就输出,并且在hashmap中减一。
//空间换时间
vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
vector<int> temp;
map<int,int> mapnum;
for(int i=0;i<nums1.size();i++)
{
mapnum[nums1[i]]++;
}
for(int j=0;j<nums2.size();j++)
{
if(mapnum[nums2[j]])
{
temp.push_back(nums2[j]);
mapnum[nums2[j]]--;
}
}
return temp;
}
121. 买卖股票的最佳时机【easy】
看题解学习了一个单调栈解法,制造一个单调递增栈。
我使用一个变量保存了栈底元素,用单调栈的栈顶减去栈低就是利益。
使用一个变量sum计算利益(每进栈一个数就算一次),然后取ans=max(sum,ans),最后留下的ans就是最大利益。
上代码
int maxProfit(vector<int>& prices) {
stack<int> a;
int bottom;
int ans=0;
int sum=0;
for(int i=0;i<prices.size();i++)
{
if(a.empty()==true)
{
a.push(prices[i]);
bottom=prices[i];
}
else
{
while(a.empty()==false && a.top()>prices[i])
{
a.pop();
}
if(a.empty()==true)
{
a.push(prices[i]);
bottom=prices[i];
}
else if(a.top()<prices[i])
{
a.push(prices[i]);
sum=a.top()-bottom;
ans=max(sum,ans);
}
}
}
return ans;
}
566.重塑矩阵【easy】
在 MATLAB 中,有一个非常有用的函数 reshape ,它可以将一个 m x n 矩阵重塑为另一个大小不同(r x c)的新矩阵,但保留其原始数据。
给你一个由二维数组 mat 表示的 m x n 矩阵,以及两个正整数 r 和 c ,分别表示想要的重构的矩阵的行数和列数。
重构后的矩阵需要将原始矩阵的所有元素以相同的 行遍历顺序 填充。
如果具有给定参数的 reshape 操作是可行且合理的,则输出新的重塑矩阵;否则,输出原始矩阵。
这个题比较简单,我的思路是
1.如果前后矩阵的总数字个数不一致,直接return
如果前矩阵的行数等于后矩阵的列数,直接return
2.遍历前矩阵的每一个元素,然后对应的加到后矩阵中。使用一个变量p控制后矩阵换行,当p==后矩阵的列数时,让p=0,把现有的数据加到矩阵中,然后再清空数据。重复操作。
vector<vector<int>> matrixReshape(vector<vector<int>>& mat, int r, int c) {
vector<int> temp = mat[0];
if(mat.size()==r || temp.size()*mat.size()!=r*c)
return mat;
int p=0;
vector<vector<int>> ans; //后矩阵
vector<int> a; //后矩阵的每一行
for(int i=0;i<mat.size();i++)
{
temp = mat[i];
for(int j=0;j<temp.size();j++)
{
a.push_back(temp[j]);
p++;
if(p==c)
{
p=0;
ans.push_back(a);
a.clear();
}
}
}
return ans;
}
118.杨辉三角
给定一个非负整数 numRows,生成「杨辉三角」的前 numRows 行。
在「杨辉三角」中,每个数是它左上方和右上方的数的和。
是一个比较笨笨的方法0.0,就是在第一行和第二行的时候单独处理(全为1),下面的每一行:
1,第一个数和最后一个数都是1
2,其他的每个数等于上一行的第j-1和第j个数的和
vector<vector<int > > generate(int numRows)
{
vector<vector<int > > ans;
vector<int> line;
vector<int> temp;
for(int i=0;i<numRows;i++)
{
if(i==0)
{
line.push_back(1);
ans.push_back(line);
line.clear();
}
else if(i==1)
{
line.push_back(1);
line.push_back(1);
ans.push_back(line);
line.clear();
}
else
{
for(int j=0;j<=i;j++)
{
if(j==0)
line.push_back(1);
else if(j==i)
{
line.push_back(1);
ans.push_back(line);
line.clear();
}
else
{
temp=ans[i-1];
line.push_back(temp[j-1]+temp[j]);
}
}
}
}
return ans;
}