2sum、3sum、4sum以及任意连续的数的和为sum、任意连续或者不连续的数的和为sum...

2sum

如果数组是无序的,先排序(n*logn),然后用两个指针i,j,各自指向数组的首尾两端,令i=0,j=n-1,然后i++,j--,逐次判断a[i]+a[j]?=sum,如果某一刻a[i]+a[j]>sum,则要想办法让sum 的值减小,所以此刻i 不动,j--,如果某一刻a[i]+a[j]<sum,则要想办法让sum 的值增大,所以此刻i++,j 不动。所以,数组无序的时候,时间复杂度最终为O(n*logn+n)=O(n*logn),若原数组是有序的,则不需要事先的排序,直接O(n)搞定,且空间复杂度还是O(1),此思路是相对于上述所有思路的一种改进。

 

Pair findSum(int *s,int n,int x)
{
//sort(s,s+n); 如果数组非有序的,那就事先排好序O(N*logN)int *begin=s;int *end=s+n-1;while(begin<end) //俩头夹逼,或称两个指针两端扫描法,很经典的方法,O(N)
    {if(*begin+*end>x){--end;}else if(*begin+*end<x){++begin;}else{return Pair(*begin,*end);}178}return Pair(-1,-1);
}

 

3sum

 vector<vector<int> > threeSum(vector<int> &num) {if(num.empty())return vector<vector<int> >();sort(num.begin(),num.end());vector<vector<int> > ret;vector<int> tmp;int n=num.size();for(int i=0;i<n-2;i++){if(i>0&&num[i]==num[i-1]) continue;//防止存在重复的元素int target=-num[i];int j=i+1;int k=n-1;while(j<k){if(j<k&&k<n-1&&num[k]==num[k+1]){k--;continue;}if(num[j]+num[k]==target){tmp={num[i],num[j],num[k]};ret.push_back(tmp);j++;k--;}else if(num[j]+num[k]<target){j++;}else if(num[j]+num[k]>target)k--;}}return ret;}

4sum

    vector<vector<int> > fourSum(vector<int> &num,int target){if(num.empty())return vector<vector<int> >();sort(num.begin(),num.end());vector<vector<int> > ret;int n=num.size();int i,j;for(i=0; i<n-3; i++){//只保留第一个不重复的,其余的都删了,因为left会选择重复的if(i>=1&&num[i]==num[i-1])continue;for(j=n-1; j>i+2; j--){//只保留最后一个不重复的,其余的都删了,因为right会选择重复的if(j<n-1&&num[j+1]==num[j])continue;int left=i+1;int right=j-1;vector<int> tmp;while(left<right){//只保留最后一个不重复的,其余的都删了,因为left会选择重复的if(right<j-1&&num[right]==num[right+1]){right--;continue;}if(num[i]+num[j]+num[left]+num[right]==target){tmp= {num[i],num[left],num[right],num[j]};ret.push_back(tmp);left++;right--;}else if(num[i]+num[j]+num[left]+num[right]<target)left++;else if(num[i]+num[j]+num[left]+num[right]>target)right--;}}}return ret;}

任意连续数的和为sum(假设至少存在两个数)

void sum(int sum,int n)
{if(sum<0||n<2)return -1;int cursum=0;cursum=1+2;int i=0,j=1;while(j<=n){if(cursum==sum){int k=i;while(k<=j){cout<<k<<' ';k++;}cout<<endl;cursum-=i;i++;}else if(cursum<sum){j++;cursum+=j;}else if(cursum>sum){cursum-=i;i++;}}
}

任意数的和为sum

用回溯的方法实现:

#include<iostream>
#include<vector>
using namespace std;void findhelper(int m,int n,int start,vector<int> &path)
{if(m<0)return;if(m==0){for(auto a:path)cout<<a<<' ';cout<<endl;return;}for(int i=start; i<=n; ++i){path.push_back(i);findhelper(m-i,n,i+1,path);path.pop_back();}
}
void findSum(int m,int n)
{vector<int> path;findhelper(m,n,1,path);
}int main()
{findSum(15,20);
}

 用0-1背包法实现:

注意到取n,和不取n个区别即可,考虑是否取第n个数的策略,可以转化为一个只和前n-1个数相关的问题。

  • 如果取第n个数,那么问题就转化为“取前n-1个数使得它们的和为sum-n”,对应的代码语句就是sumOfkNumber(sum - n, n - 1);
  • 如果不取第n个数,那么问题就转化为“取前n-1个数使得他们的和为sum”,对应的代码语句为sumOfkNumber(sum, n - 1)。

实现代码:

#include<iostream>
#include<vector>
using namespace std;void findhelper(int sum,int n,vector<int> &path)
{
  //递归出口
if(sum<=0||n<=0)return;
  //输出找到的结果
if(sum==n){for(int i=path.size()-1; i>=0; --i)cout<<path[i]<<' ';cout<<n<<endl;}path.push_back(n); //典型的01背包问题findhelper(sum-n,n-1,path);//放第n个元素path.pop_back();findhelper(sum,n-1,path); //不放第n个元素 } void findSum(int m,int n) {vector<int> path;findhelper(m,n,path); }int main() {findSum(15,20); }

 存在重复元素时,求和为sum

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;void helper(vector<int> &num,vector<int> &path,int start,int sum)
{if(sum==0){for(int i=0;i<path.size();++i)cout<<path[i]<<' ';cout<<endl;return;}if(sum<0)return;for(int i=start;i<num.size();++i){if(i>start&&num[i]==num[i-1])continue;path.push_back(num[i]);helper(num,path,i+1,sum-num[i]);path.pop_back();}
}
void findSum(vector<int> &num,int sum)
{vector<int> path;sort(num.begin(),num.end());helper(num,path,0,sum);
}int main()
{vector<int> num={1,2,1,3,0,1};findSum(num,3);
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/400636.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第6章-阈值处理

第六章-阈值处理one. threshold函数&#xff1a;1. 二值化阈值处理&#xff08;cv2.THRESH_BINARY&#xff09;&#xff1a;2. 反二值化阈值处理(cv2.THRESH_BINARY_INV)3. 截断阈值化处理(cv2.THRESH_TRUNC)4. 超阈值零处理(cv2.THRESH_TOZERO_INV)5.低阈值零处理(cv2.THRESH_…

【树莓派学习笔记】二、(无屏幕)SSH远程登录、图形界面及系统配置

目录确定树莓派LAN IP使用PuTTY登陆带图形界面的远程登陆Xming方案VNC Server 方案系统配置换源(可选)备份原文件查询系统版本编辑sources.list文件同步更新源更新软件包重启树莓派固定LAN IP平台&#xff1a;树莓派3B 版本&#xff1a; 2021-05-07-raspios-buster-armhf 确定…

Centos7完全分布式搭建Hadoop2.7.3

(一&#xff09;软件准备 1&#xff0c;hadoop-2.7.3.tar.gz&#xff08;包&#xff09; 2,三台机器装有cetos7的机子 &#xff08;二&#xff09;安装步骤 1&#xff0c;给每台机子配相同的用户 进入root : su root 创建用户s: useradd s 修改用户密码&#xff1a;passwd s 2…

python学习笔记:遍历目录

import os import os.pathif __name__ __main__:root_dirg:\\downloadfor root, dirs, files in os.walk(root_dir):for dir in dirs:print root%s dir%s % (root,dir)#print rootroot dirdirfor file in files:print root%s file%s % (root,file)#print rootroot fiefile 转载…

LeetCode - Majority Element

参考了别人的想法&#xff0c;思路简洁&#xff0c;效率高。虽然是在充分理解别人的思路后写出的代码&#xff0c;但是还是发现了自己的不足之处。以后还是要多思考多写。加油吧&#xff01; public class Solution {public int majorityElement(int[] num) {int ans 0, cnt …

第7章:图像的平滑处理

第7章&#xff1a;图像的平滑处理一、均值滤波&#xff1a;二、方框滤波&#xff1a;三、高斯滤波&#xff1a;四、中值滤波五、双边滤波&#xff1a;六、2D卷积​ 图像的平滑处理是在尽量图像原有信息的情况下&#xff0c;过滤掉图像内部的噪声。由于图像平滑处理的同时通常伴…

【树莓派学习笔记】三、点亮一个LED灯(C语言 - WiringPi、Python - RPi.GPIO/GPIO Zero、bash脚本)

目录C语言WiringPiPythonRPi.GPIOGPIO Zerobash脚本平台&#xff1a;树莓派3B 版本&#xff1a; 2021-05-07-raspios-buster-armhf 若GPIO输出为3.3V 采用压降为1.7V的红色LED灯 设工作电流为15mA&#xff0c;则限流电阻取≥(3.3 - 1.7)/0.015 106.67欧较为安全。 C语言 Wi…

codevs1014 装箱问题

题目描述 Description有一个箱子容量为V&#xff08;正整数&#xff0c;0&#xff1c;&#xff1d;V&#xff1c;&#xff1d;20000&#xff09;&#xff0c;同时有n个物品&#xff08;0&#xff1c;n&#xff1c;&#xff1d;30&#xff09;&#xff0c;每个物品有一个体积&am…

OpenStack 之Nova添加扩展API流程,附带资源的查找功能

例子中涉及到SQLAlchemy 得相关操作&#xff0c;可以参考 上一随笔 Openstack 中规定&#xff0c;扩展openstack得api有两种方式 创建新的WSGI 资源扩展原有得WSGI资源得控制器&#xff08;我得理解是&#xff0c;接受到API请求后&#xff0c;具体得响应逻辑&#xff09;这两种…

转载:ASP.NET在后台代码实现个功能,根据选择提示用户是否继续执行操作

这种情况是指在后台处理一个HTTP Post命令时将时序重新交给浏览器端&#xff0c;然后运行javascript&#xff0c;然后再回到服务器端&#xff0c;然后继续进行后边的操作。如果你会画时序图&#xff0c;就可以发现这种有着两个来回通讯的程序比大多数所知道的那种只有一个来回的…

第8章:形态学操作

第8章&#xff1a;形态学操作one. 腐蚀操作&#xff1a;two. 膨胀&#xff1a;three. 通用形态学函数&#xff1a;four. 开运算&#xff1a;five. 闭运算&#xff1a;six. 形态学梯度运算&#xff1a;seven. 礼帽运算&#xff1a;eight. 黑帽运算&#xff1a;night. 核函数&…

【树莓派学习笔记】四、OpenCV的安装与卸载

目录安装修改host以连接上Github测试IP修改树莓派的hosts安装各种依赖包安装OpenCV只安装核心模块安装核心模块和opencv_contribC Opencv 测试编写测试源码编译测试卸载平台&#xff1a;树莓派3B 版本&#xff1a; 2021-05-07-raspios-buster-armhf 安装 修改host以连接上Git…

MySQL ERROR 1071 (42000): Specified key was too long; max key length is 767 bytes

今天在使用mysql时&#xff0c;又遇到了如博文标题所示的问题&#xff0c;以前针对该问题未进行记录&#xff0c;今天特意进行说明存档。 该问题是由键值字段长度过长导致。mysql支持数据库表单一键值的最大长度不能超过767字节&#xff0c;超出这个长度即报错&#xf…

转载:用大白话聊聊分布式系统

转载&#xff1a;http://blog.csdn.net/zhousenshan/article/details/71304922?locationNum10&fps1转载于:https://www.cnblogs.com/wdh1995/p/7067985.html

IE 弹出框处理经验

//各屏幕弹出窗样式 // 1366*768var style_1366x768 "dialogWidth:950px;dialogHeight:650px;help:no;center:yes;status:no;resizable:no;location:yes;"; //弹出窗口示例代码function showDialog(url,title,style) { window.showModalDialog(url, title, style…

第9章:图像梯度

第9章&#xff1a;图像梯度one. Sobel理论基础1. 计算水平方向偏导数的近似值2. 计算垂直方向偏导数的近似值two. Sobel算子及函数的使用:1. 函数语法&#xff1a;2. 对像素取绝对值&#xff1a;3. 方向&#xff1a;three. Scharr 算子及函数使用:1. 函数语法&#xff1a;2. 实…

FreeBSD9.1安装Gnome2桌面

1. #pkg_add -r xorg gnome2 gdm2. #ee /etc/rc.conf  加入hald_enable"YES" dbus_enable"YES gdm_enable"YES" gnome_enable"YES" 3. # /usr/local/etc/rc.d/dbus start # /usr/local/etc/rc.d/hald start4. # ee /etc/fstab 加入pro…

【树莓派学习笔记】五、处理、自动重命名并另存为图片

目录编写源码编译测试平台&#xff1a;树莓派3B 版本&#xff1a; 2021-05-07-raspios-buster-armhf 编写源码 所用源码修改自【机器视觉学习笔记】最近邻插值实现图片任意角度旋转&#xff08;C&#xff09; 在合适的地方编写源码 nano main.cpp#include <opencv2/openc…

【bzoj3744】Gty的妹子序列 分块+树状数组+主席树

题目描述 我早已习惯你不在身边&#xff0c;人间四月天 寂寞断了弦。回望身后蓝天&#xff0c;跟再见说再见……某天,蒟蒻Autumn发现了从 Gty的妹子树(bzoj3720) 上掉落下来了许多妹子,他发现她们排成了一个序列,每个妹子有一个美丽度。Bakser神犇与他打算研究一下这个妹子序列…

Linux系统软件包的管理   3月30日课程

Linux系统软件包的管理一、 rpm工具rpm Redhat Package Manager&#xff0c; 设计理念是开放的&#xff0c;不仅仅是在RedHat平台上&#xff0c;在SUSE上也是可以使用的。rpm包名字构成由-和.分成了若干部分&#xff0c;如abrt-cli-2.0.8-15.el6.centos.i686.rpm&#xff0c;ab…