之前的内容涉及的是数组删除的内容的题型,这次内容还是数组只不过思考的方式可能基础算法的合并使用,废话不多说,直接贴题;
leetcode 215数组第k大的数,就是求数组中的第k大的数,如果采用一般的解题思路就是从大到小排序,然后取下标为k-1的值,时间复杂度排序的时间复杂度O(nlog(n))
算法改进:采用快速排序中的pivot的思路,结合二分法思路
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
//采用快速排序的方式时间复杂度为O(nlogn)
int size=nums.size();
if(k>size)
return -1;
int right=nums.size()-1;
int left=0;
while(left<=right){
int pivot=nums[left];
int i=left;
int j=right;
while(i<j){
while(i<j&&nums[j]<pivot){
j--;
}
if(i<j){
swap(nums[i++],nums[j]);
}
while(i<j&&nums[i]>=pivot){
i++;
}
if(i<j){
swap(nums[i],nums[j--]);
}
}
if(j==k-1){
return nums[j];
}
else if(j<k-1){
left=j+1;
}
else{
right=j-1;
}
}
}
private:
void swap(int& num1,int& num2){
int temp;
temp=num1;
num1=num2;
num2=temp;
}
};
时间复杂度一定是小于O(nlog(n))
leetcode88 Merge Sorted Array这道题是比较频繁的一道题
比较简单的思路是开辟一个新的数组空间,空间复杂度为O(m+n)
算法改进:
class Solution {
public:
void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
//学会使用C++中insert的函数的使用
//第一个版本是时间复杂度太高了
//下面的版本是本地最优的算法 如果有一个新的存储空间 那么空间复杂度是O(m+n) 本地实现的算法;不需要额外的存储空间
//这道题的前提是数组1的空间是无限大的,所以不需要考虑数组索引的问题
int i=m-1;
int j=n-1;
int k=m+n-1;
while(i>=0&&j>=0){
if(nums1[i]>nums2[j]){
nums1[k--]=nums1[i--];
}
else{
nums1[k--]=nums2[j--];
}
}
while(j>=0){
nums1[k--]=nums2[j--];
}
return ;
}
};
接下来的这道题和在001中的two sum是相同的,只不过更加简单了,这里采用的思路就是 对撞指针(Orz高级叫法)
leetcode167 Two Sum II - Input array is sorted
class Solution {
public:
vector<int> twoSum(vector<int>& numbers, int target) {
vector<int> ans;
int i=0;
int size=numbers.size()-1;
int j=size;
while(i<j){
if((numbers[i]+numbers[j])>target){
j--;
}
else if((numbers[i]+numbers[j])<target){
i++;
}
else{
ans.push_back(i+1);
ans.push_back(j+1);
return ans;
}
}
return ans;
}
};
通常对撞指针使用的比较多的时候是在将一个数组逆序;
双指针的使用方式还有就是滑动窗口的应用;
leetcode 209 求一个数组中和大于给定数字 最短长度
class Solution {
public:
int minSubArrayLen(int s, vector<int>& nums) {
int size=nums.size();
int left=0;
int right=-1;
int minlength=size+1;
int sum=0;
while(left<size){
if(sum<s&&(right+1)<size){
right++;
sum+=nums[right];
}
else{
sum-=nums[left];
left++;
}
if(sum>=s){
minlength=min(minlength,right-left+1);
}
}
if(minlength==size+1) return 0;
return minlength;
}
private:
int min(int nums1,int nums2){
if(nums1>=nums2){
return nums2;
}
else{
return nums1;
}
}
};
leetcode3 求字符串中不重复子串的最大长度;
class Solution {
public:
int lengthOfLongestSubstring(string s) {
//什么最长的问题都可以采用这种方式来进行相应的求解 使用滑动窗口方法
int size=s.size();
int maxlength=0;
int flag[256]={0};//列表初始化
int left=0;
int right=-1;//滑动窗口为闭区间
while(left<size){
if(flag[s[right+1]]==0&&(right+1)<size){
right++;
flag[s[right]]++;
}
else{
flag[s[left]]--;
left++;
}
maxlength=max(maxlength,right-left+1);
}
if(maxlength==0){
return 0;
}
return maxlength;
}
private:
int max(int num1,int num2){
if(num1>num2)
return num1;
else
return num2;
}
};