[c++] [leetcode二刷] 数组

思路总结

(1)使用哈希表空间换时间

(2)排序后使用左右指针

 

1. Remove Duplicates from Sorted Array

Given a sorted array nums, remove the duplicates in-place such that each element appear only once and return the new length.

Do not allocate extra space for another array, you must do this by modifying the input array in-place with O(1) extra memory.

Example 1:

Given nums = [1,1,2],

Your function should return length = 2, with the first two elements of nums being 1 and 2 respectively.

It doesn't matter what you leave beyond the returned length.

思路:easy

只需要两个下标,一个记录不重复所在位置,一个不断遍历即可

class Solution {
public:
    int removeDuplicates(vector<int>& nums) {
        if(nums.size() < 2) return nums.size();
        int i = 0;
        for(int j = 1;j < nums.size();j++){
            if(nums[i] != nums[j]){
                i++;
                nums[i] = nums[j];
            }
        }
        return i+1;
    }
};

 

2. Remove Duplicates from Sorted Array II

Given a sorted array nums, remove the duplicates in-place such that duplicates appeared at most twice and return the new length.

Do not allocate extra space for another array, you must do this by modifying the input array in-place with O(1) extra memory.

Example 1:

Given nums = [1,1,1,2,2,3],

Your function should return length = 5, with the first five elements of nums being 1, 1, 2, 2 and 3 respectively.

It doesn't matter what you leave beyond the returned length.

思路:medium

注意,这里不能改上面的代码,变成减2,会出现问题,1,1,1,2,2,3会变成1,1,2,3,因为第一个2移位之后,会变成1,1,2,2,2,3,造成误判,必须使用count去计次

class Solution {
public:
    int removeDuplicates(vector<int>& nums) {
        if(nums.size() < 3) return nums.size();
        int i = 1,cnt = 1;
        for(int j = 1;j < nums.size();j++){
            if(nums[j] == nums[j-1]) cnt++;
            else cnt = 1;
            if(cnt < 3) nums[i++] = nums[j];
        }
        return i;
    }
};

 

3. Longest Consecutive Sequence

Given an unsorted array of integers, find the length of the longest consecutive elements sequence.

Your algorithm should run in O(n) complexity.

Example:

Input: [100, 4, 200, 1, 3, 2]
Output: 4
Explanation: The longest consecutive elements sequence is [1, 2, 3, 4]. Therefore its length is 4.

思路:hard

怎样O(n)时间去检测顺序序列 -> 空间换时间,使用哈希表

思路1: 使用字典去记录边界的长度,不断更新

class Solution {
public:
    int longestConsecutive(vector<int>& nums) {
        if(nums.size()<2) return nums.size();
        int left = 0,right = 0;
        int res = 0;
        map<int,int> m;
        for(int num:nums){
            if(!m.count(num)){
                left = (m.count(num-1) > 0)? m[num-1]:0;
                right = (m.count(num+1) > 0)? m[num+1]:0;
                // 更新左右边界的长度
                m[num] = left+right+1;
                m[num-left] = m[num];
                m[num+right] = m[num];
                
                res = max(m[num],res);
            }
        }
        return res;
    }
};

思路2:使用set,很直观的想法,当一个数的num-1不在数组中时,说明这个num是一个上升序列的起始,因此去找这个序列的右边界

class Solution {
public:
    int longestConsecutive(vector<int>& nums) {
        if(nums.size()<2) return nums.size();
        // 初始化set
        set<int> s(nums.begin(),nums.end());
        int res=1;
        for(int num:s){
            // 只有当当前数是一个序列的起始点的时候,去判断序列长度
            if(!s.count(num-1)){
                // 找到序列最长长度
                int right = num+1;
                while(s.count(right)) right++;
                res = max(res,right-num);
            }
        }
        return res;
    }
};

 

4.Two Sum

Given an array of integers, return indices of the two numbers such that they add up to a specific target.

You may assume that each input would have exactly one solution, and you may not use the same element twice.

Example:

Given nums = [2, 7, 11, 15], target = 9,

Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].

思路:easy

(1)时间复杂度O(n^2)

因为未排序需要返回下标,故可以直接O(n^2)时间复杂度遍历

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        vector<int> res;
        for(int i = 0;i < nums.size();i++){
            for(int j = i+1;j < nums.size();j++){
                if(nums[i]+nums[j] == target){
                    res.push_back(i);
                    res.push_back(j);
                    return res;
                }
            }
        }
        return res;
    }
};

(2)空间换时间,时间复杂度O(N)

这里思路跟上一题很像,充分利用哈希表的特性

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        map<int,int> m;
        vector<int> res;
        for(int i = 0;i < nums.size();i++){
            m[nums[i]] = i;
        }
        for(int i = 0;i < nums.size();i++){
            int num_j = target-nums[i];
            // 注意这里m[num_j] != i,确保不会取到自己
            if(m.count(num_j) && m[num_j] != i){
                res.push_back(i);
                res.push_back(m[num_j]);
                break;
            }
        }
        return res;
    }
};

 

5.3Sum

Given an array nums of n integers, are there elements abc in nums such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.

Note:

The solution set must not contain duplicate triplets.

Example:

Given array nums = [-1, 0, 1, 2, -1, -4],

A solution set is:
[
  [-1, 0, 1],
  [-1, -1, 2]
]

思路:medium

(1)怎样去重:sort之后判断

(2)3 sum是2 sum的变形,排序后使用2 sum,时间复杂度O(n^2)

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int>> res;
        if(nums.size() < 3) return res;
        // 排序:便于去重,同时2sum时间负责度变为O(n)
        sort(nums.begin(),nums.end());
        
        for(int i = 0;i < nums.size()-2;i++){
            int target = 0-nums[i];
            if(i == 0 || (i > 0 && nums[i] != nums[i-1])){
                int j = i+1,k = nums.size()-1;
                while(j < k){
                    if(nums[j]+nums[k] == target){
                        vector<int> cur{nums[i],nums[j],nums[k]};
                        res.push_back(cur);
                        while(j < k && nums[j+1] == nums[j]) j++;
                        while(k > j && nums[k-1] == nums[k]) k--;
                        j++;k--;
                    }
                    else if (nums[j]+nums[k] < target) j++;
                    else k--;
                }
            }  
        }
        return res;
    }
};

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
电子图书资源服务系统是一款基于 Java Swing 的 C-S 应用,旨在提供电子图书资源一站式服务,可从系统提供的图书资源中直接检索资源并进行下载。.zip优质项目,资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松copy复刻,拿到资料包后可轻松复现出一样的项目。 本人系统开发经验充足,有任何使用问题欢迎随时与我联系,我会及时为你解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(若有),项目具体内容可查看下方的资源详情。 【附带帮助】: 若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步。 【本人专注计算机领域】: 有任何使用问题欢迎随时与我联系,我会及时解答,第一时间为你提供帮助,CSDN博客端可私信,为你解惑,欢迎交流。 【适合场景】: 相关项目设计中,皆可应用在项目开发、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面中 可借鉴此优质项目实现复刻,也可以基于此项目进行扩展来开发出更多功能 【无积分此资源可联系获取】 # 注意 1. 本资源仅用于开源学习和技术交流。不可商用等,一切后果由使用者承担。 2. 部分字体以及插图等来自网络,若是侵权请联系删除。积分/付费仅作为资源整理辛苦费用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值