leetcode:数组

leetcode1:求数组和为target的两数

O(n2)的解法

双层遍历

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

测试用例时间和空间:

29 / 29 test cases passed.
Status: Accepted
Runtime: 144 ms
Memory Usage: 9.2 MB

O(n)的解法

使用hash map,开始时hash_map为空,依次遍历数组:
1.如果target - nums[i]的值在hash map中就找到了,将下标放到result中
2.如果target - nums[i]的值hash map中就没有找,将nums[i]放入到hash map中等待之后的值查找

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        vector<int> result;
        int calculate_num = 0;
        unordered_map<int, int> hash_map;
         unordered_map<int, int>::iterator item;
        for(int i=0; i<nums.size(); i++)
        {
            calculate_num = target - nums[i];
            item = hash_map.find(calculate_num);
            if(item != hash_map.end() )
            {
                    result.push_back(item->second);
                    result.push_back(i);
                    return result;
            }
            
            hash_map[nums[i]]=i;
        }
        return result;
    }
};

测试用例时间和空间:


29 / 29 test cases passed.
Status: Accepted
Runtime: 12 ms
Memory Usage: 10 MB

O(n)的解法优化1

unordered_map的count方法速度比find速度快很多,因为count存在返回1,不存在返回0,而find需要返回下标,所以这里这count 代替find。

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        vector<int> result;
        int calculate_num = 0;
        unordered_map<int, int> hash_map;
        for(int i=0; i<nums.size(); i++)
        {
            calculate_num = target - nums[i];
            if(hash_map.count(calculate_num) )
            {
                    result.push_back(hash_map[calculate_num]);
                    result.push_back(i);
                    return result;
            }
            
            hash_map[nums[i]]=i;
        }
        return result;
    }
};

测试用例时间和空间:

29 / 29 test cases passed.
Status: Accepted
Runtime: 4 ms
Memory Usage: 10.2 MB

leetcode26:删除数组中重复的值

测试地址

双指针解法

设置两个指针,slow和fast,如果发现有相同的值fast++直到不同。

class Solution {
public:
    int removeDuplicates(vector<int>& nums) {
        if( nums.empty() )
            return 0;
        int slow = 0;
        int fast = 1;
        
        while(fast < nums.size())
        {
            if(nums[slow] == nums[fast])
            {
                fast++;
                continue;
            }
            slow++;
            nums[slow]=nums[fast];
        }
        return slow+1;        
    }
};

leetcode54:螺旋矩阵

测试地址
在这里插入图片描述

解法

定义对角两个点4个坐标分别为(0,0),(c2,r2),然后一层一层的螺旋的输入到result数组中。

class Solution {
public:
    vector<int> spiralOrder(vector<vector<int>>& matrix) {
         if(matrix.empty()) return vector<int>();
         int c1 = 0;
         int c2 = matrix[0].size() -1;
         int r1 = 0;
         int r2 = matrix.size()  -1;
         int size =  matrix[0].size() * matrix.size();
         vector<int> result;
        result.reserve(size);  //预先设置大小,以免vector扩容时耗费时间
         while(true){  
                for(int c = c1; c <= c2; c++) result.push_back(matrix[r1][c]);
                r1++; //每遍历完一行或者一列就缩小范围
                if(r1 > r2)  break;

                for(int r = r1; r <= r2; r++) result.push_back(matrix[r][c2]);
                c2--;
                if(c1 > c2) break;

                for(int c = c2; c >= c1; c--) result.push_back(matrix[r2][c]);
                r2--;
                if(r1 > r2) break;

                for(int r = r2; r >= r1; r--) result.push_back(matrix[r][c1]);
                c1++;
                if(c1 > c2) break;
        }
        return result;
    }
};    

leetcode56:合并区间

测试地址
先进行排序,申请一个vector<vector> result保存新的,遍历intervals:
1.如果result为空表示第一个,直接插入;或者result最后一个小于现在的第一个,表示不想交。则直接插入
2.如果相加就将result最后个和现在的第一个进行比较,选择大的,相当于合并空间。

class Solution {
public:
    vector<vector<int>> merge(vector<vector<int>>& intervals) {
        sort(intervals.begin(), intervals.end());   //先排序
        vector<vector<int>> result;
        for(auto &interval : intervals)
        {
            if(result.empty() || result.back().back()< interval.front()) 
                result.push_back(interval);
            else
                 result.back().back() = max(result.back().back(),interval.back());
        }
        return result;
    }
};

测试时间

169 / 169 test cases passed.
Status: Accepted
Runtime: 24 ms
Memory Usage: 12.3 MB

优化1

不要将最大的赋值,而是比较需要赋值再赋值,较少赋值的次数。可以减少时间。

class Solution {
public:
    vector<vector<int>> merge(vector<vector<int>>& intervals) {
        sort(intervals.begin(), intervals.end());   //先排序
        vector<vector<int>> result;
        for(auto &interval : intervals)
        {
            if(result.empty() || result.back().back()< interval.front()) 
                result.push_back(interval);
            else{
                if( result.back().back() > interval.back())
                    continue;
                else
                    result.back().back() = interval.back();
            }
        }
        return result;
    }
};

测试时间


169 / 169 test cases passed.
Status: Accepted
Runtime: 16 ms
Memory Usage: 12.3 MB

leetcode4: 求两个有序数组的中位数

O(log(min(len1,len2)))时间复杂度

参考地址

class Solution {
public:
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        double result = 0;
        if(nums1.size() <= nums2.size())
            result = findMedianSortedArrays_help(nums1,nums2);
        else
            result = findMedianSortedArrays_help(nums2,nums1);
        
        return result;
    }
    
    double findMedianSortedArrays_help(vector<int>& nums1, vector<int>& nums2) //需要长度小的数组在前面,防止第二个数组数组越界
    {
        if(nums2.empty())   //两个数组都为空时
            return 0.0;
        if(nums1.empty())  //第一个数组为空
        {
            if(nums2.size() & 1 != 0 )
                return nums2[nums2.size()/2]*1.0;
            else
                return (nums2[(nums2.size()-1)/2] + nums2[nums2.size()/2])/2.0;
        }
        double aux = (nums1.size() + nums2.size() + 1)/2.0;   //假设两个数组合并后的中位数的位置
        int min_i = 0;
        int max_i = nums1.size();
        while(min_i <= max_i)
        {
            int i = (min_i + max_i)/2; //二分法找到合适的i和j
            int j = aux - i;
            if(i>0 && nums1[i-1] > nums2[j])
            {
                max_i = i - 1;
            }else if(i < nums1.size() && nums1[i] < nums2[j-1]){
                min_i = i + 1;
            }else{
                int max_left = 0; 
                if(i == 0)
                    max_left = nums2[j-1];
                else if(j == 0)
                    max_left = nums1[i-1];
                else
                    max_left = max(nums1[i-1], nums2[j-1]);
                
                if((nums1.size() + nums2.size()) & 1 != 0)  //两个数组长度和为奇数
                    return max_left*1.0;
                
                //如果两个数组长度和为偶数
                int min_right = 0;
                if(i == nums1.size())
                    min_right = nums2[j];
                else if(j == nums2.size())
                    min_right = nums1[i];
                else
                    min_right = min(nums1[i], nums2[j]);
                
                return (max_left + min_right)/2.0;
            }
        }
        return -1.0;
    }
};

时间消耗:


2085 / 2085 test cases passed.
Status: Accepted
Runtime: 36 ms
Memory Usage: 9.6 MB

leetcode349:求两个数组的交集

这里仅仅在刷leetcode时将好的解法记录下来,过程中可能参考其他人的好的解法,并非原创,但是不是博客,所以无法转载。

c++ hash解法

将第一个数组放到一个unordered_set中,再逐个统计第二个数组中的元素是否在已经在这个unordered_set中存在,如果存在就将这个数加到结果数组中,并删除unordered_set中的元素,最后输出结果。

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        unordered_set hash_set(nums1.begin(), nums1.end());
        vector<int> result;
        
        for(auto num : nums2)
        {
            if(hash_set.count(num))
            {
                result.emplace_back(num);
                hash_set.erase(num);
            }
        }
        
        return result;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值