之前的内容涉及的是数组删除的内容的题型,这次内容还是数组只不过思考的方式可能基础算法的合并使用,废话不多说,直接贴题;
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; } };