面试经典 150 题 -- 数组 / 字符串 (总结)

总的链接

面试经典 150 题 - 学习计划 - 力扣(LeetCode)全球极客挚爱的技术成长平台

88.合并两个有效数组

因为有序,直接设置双指针置于两个数组的末尾,从后往前直接模拟就好了,贪心的比较两个指针所指元素,优先挑出大的,放入答案数组中去;

cpp 复制代码
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时,将其加入新数组中,否则直接跳过即可;

cpp 复制代码
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.删除有序数组中的重复项

思路 : 还是双指针模拟,思路与上题类似;

cpp 复制代码
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,那么只将两个加入新数组即可;

cpp 复制代码
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的元素,那么在排好序之后,该元素其中的一个一定会出现在数组最中间 ;

cpp 复制代码
class Solution {
public:
    int majorityElement(vector<int>& nums) {
     sort(nums.begin(),nums.end());
     return nums[nums.size()/2];
    }
};

法二 (哈希表暴力枚举):

思路 : 利用hash表统计每个元素出现次数,然后枚举哈希表,找到次数最大的元素;这里优化为边遍历边统计;

cpp 复制代码
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;
    }
};

法三(摩尔投票法)

利用摩尔投票法,来解决此题,详情请看代码 :

java 复制代码
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] ,详细请看代码 :

cpp 复制代码
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 ; 一遍遍历,循环更新答案就好 ;

cpp 复制代码
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买,就会造成最优的结果 ;

cpp 复制代码
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即可;

cpp 复制代码
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;
    }
};
相关推荐
小飞猪Jay33 分钟前
C++面试速通宝典——13
jvm·c++·面试
Kalika0-01 小时前
猴子吃桃-C语言
c语言·开发语言·数据结构·算法
sp_fyf_20241 小时前
计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-10-02
人工智能·神经网络·算法·计算机视觉·语言模型·自然语言处理·数据挖掘
我是哈哈hh3 小时前
专题十_穷举vs暴搜vs深搜vs回溯vs剪枝_二叉树的深度优先搜索_算法专题详细总结
服务器·数据结构·c++·算法·机器学习·深度优先·剪枝
Tisfy3 小时前
LeetCode 2187.完成旅途的最少时间:二分查找
算法·leetcode·二分查找·题解·二分
Mephisto.java3 小时前
【力扣 | SQL题 | 每日四题】力扣2082, 2084, 2072, 2112, 180
sql·算法·leetcode
robin_suli3 小时前
滑动窗口->dd爱框框
算法
丶Darling.3 小时前
LeetCode Hot100 | Day1 | 二叉树:二叉树的直径
数据结构·c++·学习·算法·leetcode·二叉树
labuladuo5204 小时前
Codeforces Round 977 (Div. 2) C2 Adjust The Presentation (Hard Version)(思维,set)
数据结构·c++·算法
jiyisuifeng19914 小时前
代码随想录训练营第54天|单调栈+双指针
数据结构·算法