今天总结了一下leetcode上数组的题,leetcode上数组的题实在是太多了,这里只对前150题进行了归纳,选择一些比较经典的题总结;
leetcode1:Two sum
计算两个数的和等于一个目标结果,传统暴力算法:遍历两次,计算出相应的和,然后用一个vector<int>来保存数据然后返回,时间复杂度为O(n^2);
算法改进:首先将数组进行排序,然后采用两个指针,一个指针指向数组起始的位置,一个指向数组终止的位置,如果两数相加大于target,将右指针左移,两数相加小于target将左指针右移,直到两指针相遇;算法的时间复杂度为O(nlogn+n)
//设置全局变量,将值和索引相应的包装起来
struct number{
int num;
int index;
number(int num_,int index_):num(num_),index(index_){}
};
bool mycompare(struct number &number1, struct number &number2){
return number1.num<number2.num;
}
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
vector<number> numtemp;
for(int i=0;i<nums.size();i++){
numtemp.push_back(number(nums[i],i));//将相应的结构体添加到vector中用于排序
}
sort(numtemp.begin(),numtemp.end(),mycompare);
int i=0;
int j=numtemp.size()-1;
vector<int> result;
while(i<j){
if((numtemp[i].num+numtemp[j].num)<target){
i++;
}
else if((numtemp[i].num+numtemp[j].num)>target){
j--;
}
else{
result.push_back(numtemp[i].index);
result.push_back(numtemp[j].index);
return result;
}
}
算法的运行时间为8ms
一下是Python版本:
class Solution:
def twoSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
# temp=sorted(nums)
# length=len(temp)
# i=0;
# j=length-1
# ans=[]
# while(i<j):
# if(temp[i]+temp[j])<target:
# i+=1
# elif(temp[i]+temp[j])>target:
# j-=1
# else:
# ans.append(nums.index(temp[i]))
# if(temp[i]==temp[j]):
# ans.append(nums.index(temp[j]))
# else:
# ans.append(nums.index(temp[j]))
# return ans
# 以上方案不能表示相等的时候的数据 原因就是index函数的问题
length=len(nums)
tempnum=[]
for i in range(length):
tempnum.append([nums[i],i])
tempnum.sort(key=lambda x:x[0])
i=0
j=length-1
ans=[]
while(i<j):
if(tempnum[i][0]+tempnum[j][0])<target:
i+=1
elif(tempnum[i][0]+tempnum[j][0])>target:
j-=1
else:
ans.append(tempnum[i][1])
ans.append(tempnum[j][1])
return ans
算法的运行时间是70ms 我的天效率也太低了吧
解决了leetcode1的问题那么其余3sum,4sum, 3sum closed(leetcode15,leetcode16,leetcode18) 这三个题没什么好说的了
接下来解决的是:leetcode11:
题目分析: 求所能存储水的容量,水的存储容量是由最短板所决定的,所以对于该问题,设置两个指针,一个指向数组头i,一个指向数组尾j,如果左指针指向的值小于右指针指向的值,那么最大容量就是(nums[i]*(j-i)),否则就是num[j]*(j-i), 对于第一种情况,如果还想要找到更大的容量,就需要将左指针右移,对于第二种情况就是将右指针左移,直到两指针相遇。
以下是C++代码:
class Solution {
public:
int maxArea(vector<int>& height) {
int i=0;
int size=height.size();
int max=0;
int sum=0;
int j=size-1;
while(i<j){
if(height[i]<=height[j]){
sum=height[i]*(j-i);
i++;
if(sum>max){
max=sum;
}
}
else if(height[i]>height[j]){
sum=height[j]*(j-i);
j--;
if(sum>max){
max=sum;
}
}
}
return max;
}
};
算法的运行时间是20ms
以下是Python代码
class Solution(object):
def maxArea(self, height):
"""
:type height: List[int]
:rtype: int
"""
lenght=len(height)
maxsum=0
numsum=0
i=0;
j=lenght-1
while(i<j):
if(height[i]<height[j]):
numsum=height[i]*(j-i)
if numsum>maxsum:
maxsum=numsum
i+=1
else:
numsum=height[j]*(j-i)
if(numsum>maxsum):
maxsum=numsum
j-=1
return maxsum
运行时间为63m
接下来是LeetCode26,统计出不重复的元素的个数,分析采用一次遍历,时间复杂度为O(n)的方式
C++代码如下:
class Solution {
public:
int removeDuplicates(vector<int>& nums) {
int i=0;
int size=nums.size();
while(i<size-1){
if(nums[i]==nums[i+1]){
vector<int>::iterator it=nums.begin()+i;
nums.erase(it);
size--;
}
else{
i++;
}
}
return nums.size();
}
};
由于在处理删除的时候边界条件怎么好控制直接用stl中的函数实现了
运算时间46ms
下面是Python代码:(直接使用函数即可)使用numpy不要太简单;
解决了这个题相应的leetcode27 也不是难事;