2021-07-23

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

提示:这里可以添加本文要记录的大概内容:
例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。


提示:以下是本篇文章正文内容,下面案例可供参考

一、差分数组

算法原型
比如我们现在有一个数组arr,arr={0,2,5,4,9,7,10,0}
在这里插入图片描述

那么差分数组是什么呢?其实差分数组本质上也是一个数组,我们暂且定义差分数组为d,差分数组d的大小和原来arr数组大小一样,而且d[i]=arr[i]-arri-1,且d[i]=0,它的含义是什么?就是原来数组i位置上的元素和i-1位置上的元素作差,得到的值就是d[i]的值。

所以,例子中的arr数组其对应的差分数组值如下图所示。
在这里插入图片描述

那么构造了这么个玩意有什么用呢?难道是来浪费宝贵的内存空间的?嗯,确实是来浪费宝贵的内存了,但是却换了时间上的高效。

现在我们有这么一个区间修改操作,即在区间1~4上,所有的数值都加上3.
在这里插入图片描述

我们不要傻傻地遍历arr数组的[1,4]范围,然后再分别给每个值加上3,我们此时更改差分数组d即可。

显而易见,差分数组d在[2,4]范围内的值都不用改变,只需要改变差分数组位置1和位置5的值即可,即d[1]=d[1]+3,而d[5]=d[5]-3,其余不变,为什么呢?因为差分数组的定义——d[i]=arr[i]-arr[i-1]
在这里插入图片描述

现在,我们如何根据差分数组d来推测arr中某一个位置的值呢?

比如,此时,我们想知道arr[1]的值,我们不能直接通过arr[1]得到原来的值,因为在区间修改的操作中我们并没有修改arr的值,因此我们必须从前往后遍历递推,由于d[0]=arr[0]-0(我们定义arr[0]的前一个数为0),那么arr[0]=d[0]=0,又由于d[1]=arr[1]-arr[0]=5,那么arr[1]=5+arr[0]=5。以此类推,由于d[2]=arr[2]-arr[1]=3,所以arr[2]=3+arr[1]=8。

示例:pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。

二、三数之和

问题描述:
给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。

注意:答案中不可以包含重复的三元组。

示例 1:

输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]

思路

我们固定了前两重循环枚举到的元素 aa 和 bb,那么只有唯一的 c 满足 a+b+c=0。当第二重循环往后枚举一个元素 b’时,由于 b’ > b,那么满足 a+b’+c’=0 的 c ′,一定有 c’ < c,即 c’在数组中一定出现在 cc 的左侧。也就是说,我们可以从小到大枚举 b,同时从大到小枚举 c,即第二重循环和第三重循环实际上是并列的关系。
代码如下(示例):

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        sort(nums.begin(),nums.end());
        int n=nums.size();
        
        vector<vector<int>>finl;
        for(int i=0;i<n;i++){
            if(i!=0&&nums[i]==nums[i-1]){
                continue;
            }
            int ret=0-nums[i];
            int k=n-1;
            for(int j=i+1;j<n;j++){
                if(j!=i+1&&nums[j]==nums[j-1]){
                    continue;
                }
                while(j<k&&nums[j]+nums[k]>ret){
                    k--;
                }
                if(j==k){
                    break;
                }
                if(nums[j]+nums[k]==ret){
                    vector<int>temp;
                    temp.push_back(nums[i]);
                     temp.push_back(nums[j]);
                      temp.push_back(nums[k]);
                      finl.push_back(temp);
                } 
            }
        }
        return finl;
    }
};

2.1、构成三角形

题目描述:给定一个包含非负整数的数组,你的任务是统计其中可以组成三角形三条边的三元组个数。
输入: [2,2,3,4]
输出: 3
解释:
有效的组合是:
2,3,4 (使用第一个 2)
2,3,4 (使用第二个 2)
2,2,3
思路:双指针思路(与三数之和类似),固定最大边,移动两小边

class Solution {
public:
   
    int triangleNumber(vector<int>& nums) {
        // 先排序, 然后 a < b < c, 对应指针为 i,j,k, 固定k (k一开始=len-1, 最后k>=2), 剩下两个数用双指针找
        int len = nums.size();
        if (len < 3) return 0;
        sort(nums.begin(), nums.end());
        int groupCount = 0;
        for (int k=len-1; k >= 2; k--) 
        {
            int i = 0;
            int j = k - 1;
            while (i < j)
            {
                if (nums[i] + nums[j] > nums[k])
                {
                    groupCount += j - i;  /* 对于每一趟(k确定时): 只要出现第1次满足要求的, 则只要j对应的数还在i对应数的右侧, 就可以继续统计。当 j = i+1时只要1组, 于是该情形下共有j-i组。最后把每一趟的组合数相加 */
                    j--;
                }
                else i++;
            }
        }

        return groupCount;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值