总的链接
面试经典 150 题 - 学习计划 - 力扣(LeetCode)全球极客挚爱的技术成长平台
88.合并两个有效数组
因为有序,直接设置双指针置于两个数组的末尾,从后往前直接模拟就好了,贪心的比较两个指针所指元素,优先挑出大的,放入答案数组中去;
class Solution {
public: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;}}
};
27.移除元素
题意 : 在nums中原地移除值=val的数,然后返回新数组的长度;
思路 : 模拟即可,设置双指针,一个j指向新数组的尾下标,一个i指向原数组,一遍遍历,当nums[i]!=val时,将其加入新数组中,否则直接跳过即可;
class Solution {
public:int removeElement(vector<int>& nums, int val) {int n = nums.size() ;int i=0,j=0;for(;i<n;i++){if(nums[i]!=val) nums[j++] = nums[i];}return j ;}
};
26.删除有序数组中的重复项
思路 : 还是双指针模拟,思路与上题类似;
class Solution {
public:int removeDuplicates(vector<int>& nums) {int j=0;int n = nums.size() ;for(int i=0;i<n;i++){int k = i + 1 ;while(k<n && nums[k]==nums[i]) k ++;nums[j++] = nums[i];i = k - 1 ; }return j ;}
};
80 . 删除有序数组中的重复项 II
思路 : 上一题多了一个保留两个重复元素,那么在枚举的过程中,发现重复的元素数量>=2,那么只将两个加入新数组即可;
class Solution {
public:int removeDuplicates(vector<int>& nums) {int j=0;int n = nums.size() ;for(int i=0;i<n;i++){int k = i + 1 ;while(k<n && nums[k]==nums[i]) k ++;if(k-i>=2){nums[j++] = nums[i];nums[j++] = nums[i];}else{nums[j++] = nums[i];}i = k - 1 ; }return j ;}
};
169.多数元素
法一(众数理论) :
思路 : 众数理论,由于在题目当中的众数定义为出现次数>=n/2的元素,那么在排好序之后,该元素其中的一个一定会出现在数组最中间 ;
class Solution {
public:int majorityElement(vector<int>& nums) {sort(nums.begin(),nums.end());return nums[nums.size()/2];}
};
法二 (哈希表暴力枚举):
思路 : 利用hash表统计每个元素出现次数,然后枚举哈希表,找到次数最大的元素;这里优化为边遍历边统计;
class Solution {
public:int majorityElement(vector<int>& nums) {int n = nums.size();unordered_map<int,int> counts;int cnt = 0;int ma;for(int num : nums){++counts[num];if(counts[num] > cnt){ma = num;cnt = counts[num];}}return ma;}
};
法三(摩尔投票法)
利用摩尔投票法,来解决此题,详情请看代码 :
class Solution {public int majorityElement(int[] nums) {int x = 0 , votes = 0 ;for(int num : nums){if(votes == 0) x = num ;votes += num == x ? 1 : -1 ;}return x ;}
}
189.轮转数组
思路 : 首先先复制nums数组到res中,保留元素组的情况,对于右移k位,那么也就是nums[(i+k)%n] = res[i] ,详细请看代码 :
class Solution {
public:void rotate(vector<int>& nums, int k) {int n = nums.size();vector<int> res(n);for(int i=0;i<n;i++) res[i] = nums[i];for(int i=0;i<n;i++){nums[(k+i)%n] = res[i];}}
};
121 . 买卖股票的最佳时机
思路 : 一遍遍历,在遍历的过程中,用pre存前面的最小元素,那么对于第i天如果要卖股票的话,那么最大收益就是prices[i]-pre ; 一遍遍历,循环更新答案就好 ;
class Solution {
public:int maxProfit(vector<int>& prices) {int n = prices.size() ;int mi = prices[0] ;int ans = 0 ;for(int i=1;i<n;i++){ans = max (ans , prices[i] - mi);mi = min(mi , prices[i]);}return ans ;}
};
122 . 买卖股票的最佳时机 II
这题就直接遍历就好了,举个例子 :
3 1 5 , 那么ans = 5 - 1
1 2 4 , 那么ans = 4 - 1 = 4-2+2-1
用贪心的思路,相邻两个, 只要p[i]>p[i-1],那么就在前一天买,第i买,就会造成最优的结果 ;
class Solution {
public:int maxProfit(vector<int>& prices) {int ans = 0;for(int i=1;i<prices.size();i++){int tmp = prices[i] - prices[i-1];ans += tmp>0 ? tmp : 0;}return ans;}
};
55.跳跃游戏
一遍遍历 ,记录当前能够达到的最远距离k,如果 i > k 表示到不了,直接返回false即可,在循环的过程中更新k即可;
class Solution {
public:bool canJump(vector<int>& nums) {int k = 0;for(int i=0;i<nums.size();i++){if(i>k) return false;k = max(k,i+nums[i]);}return true;}
};