leetcode之数组左右夹逼法
来源:互联网 发布:兄弟绣花机软件 编辑:程序博客网 时间:2024/06/06 07:15
一、题型:在一个数组中选出k个元素,使这k个元素的和等于目标值target。
二、分析:我们可以用k个for循环求出这k个元素,这时的时间复杂度为O(n^k)。但通过左右夹逼法可以将时间复杂度将至O(n^(k-1))。
左右夹逼法(2个元素):先对数组nums[ ]所有元素进行排序,然后数组从左右两侧向中间推进:left为当前左侧元素的下标,right为当前右侧元素的下标。若nums[left]+nums[right]<target,即当前两个元素和小于target,那么如果其中一个元素再大一点,就会更接近target,而数组此时是有序的,所以只能left向中间推进,left+1;若nums[left]+nums[right]>target,同理可得此时right向中间推进,right-1。
三、例题
1.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.
Example:
Given nums = [2, 7, 11, 15], target = 9,Because nums[0] + nums[1] = 2 + 7 = 9,return [0, 1].
UPDATE (2016/2/13):
The return format had been changed to zero-based indices. Please read the above updated description carefully.
class Solution {public: vector<int> twoSum(vector<int>& nums, int target) { unordered_map<int,int> map; vector<int> twosum; for(int i=0;i<nums.size();++i) { map[nums[i]] = i; } for(int i=0;i<nums.size();++i) { if(map.find(target-nums[i])!=map.end() && map[target-nums[i]]>i) { twosum.push_back(i); twosum.push_back(map[target-nums[i]]); break; } } return twosum; }};
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:
- Elements in a triplet (a,b,c) must be in non-descending order. (ie, a ≤ b ≤ c)
- 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)分析:原数组内出现重复的元素,但结果却不能有相同的三元组,所以在处理中要跳过相同的元素。
class Solution {public: vector<vector<int>> threeSum(vector<int>& nums) { const int size = nums.size(); vector<vector<int>> result; if(size<3) return result; sort(nums.begin(),nums.end()); const int target = 0; for(int i=0;i<size-2;i++) { int j = i+1; int k = size-1; if(i>0&&nums[i]==nums[i-1]) continue; while(j<k) { if(nums[i]+nums[j]+nums[k] < target) { ++j; while(j<k && nums[j-1]==nums[j]) j++; } else if(nums[i]+nums[j]+nums[k] > target) { k--; while(j<k && nums[k+1]==nums[k]) k--; } else { result.push_back({nums[i],nums[j],nums[k]}); j++; k--; while(j<k && nums[j]==nums[j-1] && nums[k]==nums[k+1]) { j++; --k; } } } } return result; }};
3. 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) { const int size = nums.size(); if(size<3) return 0; int closest = INT_MAX; int sum = 0; sort(nums.begin(),nums.end()); for(int i=0;i<size-2;i++) { int j = i+1; int k = size-1; while(j<k) { int temp = nums[i]+nums[j]+nums[k]; if(abs(temp-target)<closest) { closest = abs(temp-target); sum = temp; } if(temp < target) { ++j; } else if(temp > target) { k--; } else { return target; } } } return sum; }};
4. 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:
- Elements in a quadruplet (a,b,c,d) must be in non-descending order. (ie, a ≤ b ≤ c ≤ d)
- 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)
class Solution {public: vector<vector<int>> fourSum(vector<int>& nums, int target) { const int size = nums.size(); vector<vector<int>> result; if(size<4) return result; sort(nums.begin(),nums.end()); for(int i=0;i<size-3;i++) { if(i>0&&nums[i]==nums[i-1]) continue; for(int j=i+1;j<size-2;j++) { if(<span style="color:#ff0000;">j>i+1</span>&&nums[j]==nums[j-1]) continue; //j-1有可能等于i,避免nums[i]==nums[j](相当于<span style="font-family: Arial, Helvetica, sans-serif;">nums[i]==nums[j])</span><span style="font-family: Arial, Helvetica, sans-serif;">进行continue,</span> int s = j+1; int t = size-1; while(s<t) { int sum = nums[i]+nums[j]+nums[s]+nums[t]; if(sum<target) { s++; while(s<t&&nums[s]==nums[s-1]) s++; } else if(sum>target) { t--; while(s<t&&nums[t]==nums[t+1]) t--; } else { result.push_back({nums[i],nums[j],nums[s],nums[t]}); s++; t--; while(s<t&&nums[s]==nums[s-1]&&nums[t]==nums[t+1]) { s++; } } } } } return result; }};
- leetcode之数组左右夹逼法
- 算法之数组上的左右指针
- Leetcode之数组问题
- LeetCode之反转数组
- Leetcode题解之数组
- join左右数组
- leetcode:数组之Two Sum
- leetcode:数组之Remove Element
- leetcode:数组之Rotate Image
- leetcode:数组之Rotate Image
- 数组之Next Permutation---leetcode
- leetcode数组之Plus One
- leetcode数组之Rotate Image
- leetcode数组之Valid Sudoku
- hdu 1506-左右界数组
- hdu 1505-左右界数组
- leetcode解题之226# Invert Binary Tree Java版 (交换树的左右子树)
- 码农小汪剑指Offer之40-和为S的两个数字(有序数组) 左右夹逼
- mysql阅读笔记六
- LeetCode题解:Reverse Linked List
- 51nod 1092 回文字符串 dp问题
- Android应用的自动升级、更新模块的实现
- 深度学习材料:从感知机到深度网络A Deep Learning Tutorial: From Perceptrons to Deep Networks
- leetcode之数组左右夹逼法
- 动态网站访问过程——php语言
- bzoj2287【POJ Challenge】消失之物
- JavaScript特效5-完整tab选项卡
- poj 3259 Wormholes (Bellman-ford)
- bzoj1996【HNOI2010】chorus 合唱队
- iOS自定义转场动画
- quartz系列(三):定时任务的集群使用
- 使用CircularReveal动画效果切换页面