july 大神有个程序员编程艺术系列,第五章《寻找和为定值的多个数》,现在我们站在大牛的肩膀上,对leetcode上n个数求和的系列问题做个阶段性总结。


1.leetcode No.1 2sum

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].

http://blog.csdn.net/gatieme/article/details/50596965

1.1 双向扫描

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

暴力穷举的办法我们就不说了任选两个数判断和是否为输入即可
a[i]在序列中,如果a[i]+a[k]=sum的话,那么sum-a[i](a[k])也必然在序列中,举个例子,如下:

原始序列:1、2、4、7、11、15
用输入数字15 减一下各个数,得到对应的
序列为:
对应序列:14、13、11、8、4、0

第一个数组以一指针i从数组最左端开始向右扫描,第二个数组以一指针j 从数组最右端开始向左扫描,如果下面出现了和上面一样的数,即a[*i]=a[*j],就找出这俩个数来了。如上,i,j最终在第一个,和第二个序列中找到了相同的数4 和11,所以符合条件的两个数,即为4+11=15。

然后用两个指针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]

// leetcode1-2Sum.cpp : 定义控制台应用程序的入口点。
//#include "stdafx.h"
//进阶解法–基于排序O(nlogn)#include <stdlib.h>
#include <malloc.h>#define DEBUG///////////////////////////////////////////////////////////////////////////
///
///  快速排序--QuickSort
///  http://www.cnblogs.com/RootJie/archive/2012/02/13/2349649.html
///
///////////////////////////////////////////////////////////////////////////#include <stdio.h>
#include <time.h>#define MAX_SIZE 20000#define SWAP(x, y) {int t=x; x=y; y=t;}void QuickSort(int *array, int left, int right);
int Partition(int *array, int left, int right);int position[MAX_SIZE]; //  用于存储位置信息void InitPosion(int *position, int length)
{for (int pos = 0; pos < length; pos++){position[pos] = pos + 1;}
}int Partition(int *array, int left, int right)
{int pivot = array[left];while (left < right){while (left < right && array[right] >= pivot){--right;}SWAP(array[left], array[right]);SWAP(position[left], position[right]);while (left < right && array[left] <= pivot){++left;}SWAP(array[right], array[left]);SWAP(position[left], position[right]);}return left;
}void QuickSort(int *array, int left, int right)
{int pivot;if (left < right){pivot = Partition(array, left, right);QuickSort(array, left, pivot - 1);QuickSort(array, pivot + 1, right);}
}int cmp(const void *left, const void *right)
{int *left_num = (int *)left;int *right_num = (int *)right;return (*left_num - *right_num);//qsort(nums, numsSize, sizeof(nums[0]), cmp);
}int* twoSum(int* nums,      /*  the pointer which point to the array  */int numsSize,   /*  the size of the array  */int target)     /*  the sum of the two num  */
{//qsort(nums, numsSize, sizeof(nums[0]), cmp);InitPosion(position, numsSize);#ifdef DEBUG   printf("Before Quick Sort : \n");printf("Array    : ");for (int pos = 0; pos < numsSize; pos++){printf("%3d", nums[pos]);}printf("\n");printf("Position : ");for (int pos = 0; pos < numsSize; pos++){printf("%3d", position[pos]);}printf("\n");
#endif  QuickSort(nums, 0, numsSize - 1);#ifdef DEBUG   printf("After Quick Sort : \n");printf("Array    : ");for (int pos = 0; pos < numsSize; pos++){printf("%3d", nums[pos]);}printf("\n");printf("Position : ");for (int pos = 0; pos < numsSize; pos++){printf("%3d", position[pos]);}printf("\n");
#endif  int *answer = (int *)malloc(sizeof(int) * 2);int left = 0, right = numsSize - 1, sum;while (left < right){sum = nums[left] + nums[right];#ifdef DEBUGprintf("[%d, %d], %d + %d = %d\n",left, right,nums[left], nums[right], sum);
#endif  if (sum == target){
#ifdef DEBUGprintf("[%d, %d], %d + %d = %d\n",left, right,nums[left], nums[right], target);
#endifbreak;}else if (sum < target){
#ifdef DEBUGprintf("[%d, %d], %d + %d = %d\n",left, right,nums[left], nums[right], target);
#endifleft++;}else if (sum > target){
#ifdef DEBUGprintf("[%d, %d], %d + %d = %d\n",left, right,nums[left], nums[right], target);#endifright--;}}if (position[left] < position[right]){answer[0] = position[left];answer[1] = position[right];}else{answer[0] = position[right];answer[1] = position[left];}return answer;
}#ifdef DEBUGint main()
{int nums[5] = { -1, -2, -3, -4, -5 };int *answer = NULL;answer = twoSum(nums, 5, -8);printf("[%d, %d]\n", answer[0], answer[1]);
}
#endif

1.2 hash

class Solution:def twoSum(self, num, target):""":type nums: List[int]:type target: int:rtype: List[int]"""# python中字典dict类似于map的dict = {}for i in range(len(num)):   #  对于每一个num# 判断target - num[i]在不在在字典中if dict.get(target - num[i], None) == None: #如果不在dict[num[i]] = i   # 将该数存入字典中else:# 否则这两个数的和为target, 则返回return (dict[target - num[i]] , i )

2. leetcode No.15 3Sum

Given an array S of n integers, are there elements a, b, c in S 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.

For example, given array S = [-1, 0, 1, 2, -1, -4],

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

思路:
- 1,先按照由小到大把数组排序
- 2,循环取第i位,数值a[i], 后面剩余的由旁边向中间扫描,看是否符合 a[m]+a[n] == -a[i],如果a[m]+a[n]>-a[i],则向右边移动m,如果小于则向左边移动n

典型c++解法如下:

class Solution
{
public:vector<vector<int>> threeSum(vector<int>& nums) {vector<vector<int> >result;std::sort(nums.begin(), nums.end());for (unsigned int i = 0; i < nums.size(); i++){int target = -nums[i];int front = i + 1;int back = nums.size() - 1;while (front < back){int sum = nums[front] + nums[back];if (sum < target)front++;else if (sum > target)back--;else{vector<int> triplet(3, 0);triplet[0] = nums[i];triplet[1] = nums[front];triplet[2] = nums[back];result.push_back(triplet);//处理有两个同样的数的情况while (front < back && nums[front] == triplet[1])front++;while (front < back && nums[back] == triplet[2])back--;}}//处理有两个同样的数的情况while (i + 1 < nums.size() && nums[i + 1] == nums[i]) i++;}return result;}
};

3. leetcode No.16 3Sum Closest

Given an array S of n integers, find three integers in S such that the sum is closest to a given number, target. Return the sum of the three integers. You may assume that each input would have exactly one solution.

For example, given array S = {-1 2 1 -4}, and target = 1.The sum that is closest to the target is 2. (-1 + 2 + 1 = 2).
class Solution
{
public:int threeSumClosest(vector<int>& nums,int target){sort(nums.begin(),nums.end());int result = nums[0]+nums[1]+nums[2];for(int i =0;i<nums.size()-2;i++){int j = i+1,k=nums.size()-1;while(j<k){int num = nums[i] + nums[j] + nums[k];if(abs(num - target) < abs(res - target)) res = num;if(num < target) j++;else k--;}}return result;}
};

4. leetcode No.18 4Sum

Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = target? Find all unique quadruplets in the array which gives the sum of target.

Note: The solution set must not contain duplicate quadruplets.

For example, given array S = [1, 0, -1, 0, -2, 2], and target = 0.

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

// O(n^3)
class Solution {
public:vector<vector<int> > fourSum(vector<int> &nums, int target) {set<vector<int> > res;sort(nums.begin(), nums.end());for (int i = 0; i < int(nums.size() - 3); ++i) {for (int j = i + 1; j < int(nums.size() - 2); ++j) {int left = j + 1, right = nums.size() - 1;while (left < right) {int sum = nums[i] + nums[j] + nums[left] + nums[right];if (sum == target) {vector<int> out;out.push_back(nums[i]);out.push_back(nums[j]);out.push_back(nums[left]);out.push_back(nums[right]);res.insert(out);++left; --right;} else if (sum < target) ++left;else --right;}}}return vector<vector<int> > (res.begin(), res.end());}
};

5. 举一反三 n Sum

https://www.jianshu.com/p/3d1791cfba53
http://blog.csdn.net/XingKong_678/article/details/50894322
http://blog.csdn.net/yuanwei1314/article/details/42963229

输入两个整数n 和m,从数列1,2,3…….n 中随意取几个数,
使其和等于m ,要求将其中所有的可能组合列出来。

// 21 题递归方法
//copyright@ July && yansha
//July、yansha,updated。
#include<list>
#include<iostream>
using namespace std;
list<int>list1;void find_factor(int sum, int n)
{// 递归出口if(n <= 0 || sum <= 0)return;// 输出找到的结果if(sum == n){// 反转listlist1.reverse();for(list<int>::iterator iter = list1.begin(); iter != list1.end(); iter++)cout << *iter << " + ";cout << n << endl;list1.reverse();list1.push_front(n); //典型的01 背包问题find_factor(sum-n, n-1); //放n,n-1 个数填满sum-nlist1.pop_front();find_factor(sum, n-1); //不放n,n-1 个数填满sum
}int main()
{int sum, n;cout << "请输入你要等于多少的数值sum:" << endl;cin >> sum;cout << "请输入你要从1.....n 数列中取值的n:" << endl;cin >> n;cout << "所有可能的序列,如下:" << endl;find_factor(sum,n);return 0;
}

leetcode Sum 系列----寻找和为定值的多个数相关推荐

  1. java 寻找和为定值的多个数_算法笔记_037:寻找和为定值的两个数(Java)

    1 问题描述 输入一个整数数组和一个整数,在数组中查找两个数,满足他们的和正好是输入的那个整数.如果有多对数的和等于输入的整数,输出任意一对即可.例如,如果输入数组[1,2,4,5,7,11,15]和 ...

  2. Java实现寻找和为定值的多个数

    1 问题描述 输入两个整数n和sum,要求从数列1,2,3,-,n中随意取出几个数,使得它们的和等于sum,请将其中所有可能的组合列出来. 2 解决方案 上述问题是典型的背包问题的应用,即先找出n个数 ...

  3. Algorithm:C+语言实现之数组相关算法(和为定值的两个数、和为定值的m个数、荷兰国旗、长度为2n的洗牌算法、任意长度数组的洗牌算法)

    Algorithm:C+语言实现之数组相关算法(和为定值的两个数.和为定值的m个数.荷兰国旗.长度为2n的洗牌算法.任意长度数组的洗牌算法) 目录 数组 1.寻找和为定值的两个数 2.和为定值的m个数 ...

  4. leetcode17. 电话号码的字母组合--每天刷一道leetcode算法系列!

    作者:reed,一个热爱技术的斜杠青年,程序员面试联合创始人 前文回顾: leetcode1. 两数之和--每天刷一道leetcode系列! leetcode2. 两数相加--每天刷一道leetcod ...

  5. 去掉数组最后一个元素_leetcode 34. 在排序数组中查找元素的第一个和最后一个位置每天刷一道leetcode算法系列!...

    作者:reed,一个热爱技术的斜杠青年,程序员面试联合创始人 前文回顾: leetcode1. 两数之和--每天刷一道leetcode系列! leetcode2. 两数相加--每天刷一道leetcod ...

  6. LEETCODE | PYTHON | 724 | 寻找数组的中心下标

    LEETCODE | PYTHON | 724 | 寻找数组的中心下标 1. 题目 给你一个整数数组 nums ,请计算数组的 中心下标 . 数组 中心下标 是数组的一个下标,其左侧所有元素相加的和等 ...

  7. LeetCode Sum Root to Leaf Numbers (dfs)

    问题:给出一个二叉树,求从根结点到叶子结点路径上构成的所有数的和 思路:自顶向下遍历过程中,递归的终止条件是,如果是叶子结点,返回上一层的数*10加上叶子结点的值.在遍历过程中,如果存在左子树,计算左 ...

  8. 八十一、Python | Leetcode 二叉树系列(下篇)

    @Author:Runsen @Date:2020/7/6 人生最重要的不是所站的位置,而是内心所朝的方向.只要我在每篇博文中写得自己体会,修炼身心:在每天的不断重复学习中,耐住寂寞,练就真功,不畏艰 ...

  9. 七十四、Python | Leetcode数字系列(下篇)

    @Author:Runsen @Date:2020/7/3 人生最重要的不是所站的位置,而是内心所朝的方向.只要我在每篇博文中写得自己体会,修炼身心:在每天的不断重复学习中,耐住寂寞,练就真功,不畏艰 ...

最新文章

  1. 为什么说Python是伟大的入门语言
  2. 手撕设计模式之「工厂方法模式」(Java描述)
  3. MongoDB基本操作(增删改查)
  4. Android WindowManager和WindowManager.LayoutParams的使用以及实现悬浮窗口的方法
  5. 5000字权威指南分享!企业如何正确制定 IT 战略及其路线图
  6. pcb钻孔披锋改善报告_高速高频PCB技术 || 玻纤效应对高速信号的影响
  7. 全栈开发者意味着什么?
  8. 如何按页进行PDF文档拆分
  9. 【数字图像处理】基于SeetaFace2的人脸检测
  10. ANDROID仿淘宝商品浏览滑(拖)动查看详情界面
  11. C# 上位机界面添加扫码枪输入
  12. linux嵌入式做智能家居,嵌入式系统在智能家居中的应用
  13. c语言加减乘除怎么随机输入,注会机考加减乘除如何输入,注会机考加减乘除如何输入...
  14. firefoxos :add a webidl,and use
  15. 发生死锁时自动发mail
  16. bootstrap 获取表格修改的结果_BootStrap实现带有增删改查功能的表格(DEMO详解)
  17. Unity UGUI图文混排源码--优化版
  18. 送一朵玫瑰花给女朋友
  19. argparse简化版图片教程
  20. Hbase思维导图之物理模型

热门文章

  1. 莆田学院计算机在哪个校区,莆田学院有几个校区
  2. Redis源码剖析和注释(二十四)--- Redis Sentinel实现(哨兵操作的深入剖析)
  3. python统计爬取全国地铁线路站点
  4. css让文字在一行内显示
  5. 通过 FFMPEG,为视频添加字幕
  6. 高速公路收费运营安全风险管控与突发事件应急处置 PPT
  7. 架设网页游戏服务器,如何架设网页游戏服务器
  8. java套打实现_java 套打 实现
  9. python编程的就业方向_2021年python编程就业方向是怎样的?
  10. Cris 的Python笔记(十四):脑图福利