[Leetcode]15.三数之和 16.最接近的三数之和 18.四数之和 11.盛最多水的容器(双指针)

15题

补充vector 创建数组

vector<int> res;//定义一维数组
vector<vector<int>>res//定义二维数组
vector<int>(int n)//创建一个vector,元素个数为n
vector<int>(int n,const t)//创建一个vector,元素个数为n,且值均为t
vector(const vector&)//拷贝构造函数

push_back()在Vector最后添加一个元素(参数为要插入的值)

pop_back() //移除最后一个元素

clear()  //清空所有元素

empty() //判断vector是否为空,如果返回true为空

erase() // 删除指定元素

sort(nums.begin(),nums.end()) //排序

思路步骤:(排序+双指针)

1.创建一个二维数组 vector<vector<int>> res;

2.获取数组的长度 如果小于3则返回

3.对数组进行排序 sort()(从小到大)

4.for循环

  1. 判断第一个数是否大于0
  2. 去重第一步:判断 i 与 i+1是否相等   j=i+1   h=length-1
  3. 计算sum=nums[ i ]+nums[ j ]+nums[ h ] (前提 j < h)
  4. 判断sum=0?res.push_back()    
  • 去重第二部:判断 j+1与 j 是否相等 j++   判断 h+1 与 h 是否相等 h--

     5.判断sum>0? h--

     6.判断sum<0? j++

     7.返回res

主要是去重! 

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        //定义一个结果集
		vector<vector<int>> res;
		//数组的长度
		int len = nums.size();
		//当前数组的长度为空,或者长度小于3时,直接退出
		if( len <3){
			return res;
		}
		//将数组进行排序
		sort(nums.begin(),nums.end());
		//遍历数组中的每一个元素
		for(int i = 0; i<len;i++){
			//如果遍历的起始元素大于0,就直接退出
			//原因,此时数组为有序的数组,最小的数都大于0了,三数之和肯定大于0
			if(nums[i]>0){
				break;
			}
			//去重,当起始的值等于前一个元素,那么得到的结果将会和前一次相同
			if(i > 0 && nums[i] == nums[i-1]) continue;
			int l = i +1;
			int r = len-1;
			//当 l 不等于 r时就继续遍历
			while(l<r){
				//将三数进行相加
				int sum = nums[i] + nums[l] + nums[r];
				//如果等于0,将结果对应的索引位置的值加入结果集中
				if(sum==0){
					// 将三数的结果集加入到结果集中
					res.push_back(vector<int>{nums[i], nums[l], nums[r]});
					//在将左指针和右指针移动的时候,先对左右指针的值,进行判断
					//如果重复,直接跳过。
					//去重,因为 i 不变,当此时 l取的数的值与前一个数相同,所以不用在计算,直接跳
					while(l < r && nums[l] == nums[l+1]) {
						l++;
					}
					//去重,因为 i不变,当此时 r 取的数的值与前一个相同,所以不用在计算
					while(l< r && nums[r] == nums[r-1]){
						r--;
					} 
					//将 左指针右移,将右指针左移。
					l++;
					r--;
					//如果结果小于0,将左指针右移
				}else if(sum < 0){
					l++;
					//如果结果大于0,将右指针左移
				}else if(sum > 0){
					r--;
				}
			}
		}
		return res;
    }
};

16题

与15题大体相同 

  1. 对数组进行排序
  2. 先用ans获取1 2 3的和
  3. 循环i=0;i<len;i++ 定义 l =i+1  h=len-1
  • 在 l<h的前提下
  • 比较target-sum 和target-ans的绝对值大小    如果小于则 ans=sum 
  • 比较sum和target的大小 如果大于则h-- 小于则l++
  • 如果相等就直接返回ans

     4.返回ans

class Solution {
public:
	int threeSumClosest(vector<int>& nums, int target) {        
		int len=nums.size();
		sort(nums.begin(),nums.end());
		int ans=nums[0]+nums[1]+nums[2];
		for(int i=0;i<len;i++){
			int l=i+1;
			int h=len-1;
			while(l<h){
				int sum=nums[i]+nums[l]+nums[h];
				if(abs(target-sum)<abs(target-ans)){
					ans=sum;
				}
				if(sum>target){                    
					h--;
				}
				else if(sum<target){
					l++;
				}
				else {
					return ans;
				}
			}
		}
		return ans;
	}
};

18题

与15题大致相同  对数组进行排序 然后去重

c++

class Solution {
public:
    vector<vector<int>> fourSum(vector<int>& nums, int target) {
        vector<vector<int> > res;
        int len=nums.size();
        sort(nums.begin(),nums.end());
        if(len<4)
	        return res;
        for(int i=0;i<len-3;i++){
	    if(i > 0 && nums[i] == nums[i-1]) continue;
	    for(int l=i+1;l<len-2;l++){
		    if(l>i+1 && nums[l]==nums[l-1]) continue;
            int s=l+1;                
            int h=len-1;
            while(s<h){
                
                
                 if(nums[i]+nums[l]-target>-(nums[s]+nums[h])){
                    h--;
                }
                else if(nums[i]+nums[l]-target<-(nums[s]+nums[h])){
                    s++;
                }
                else
                {
                    res.push_back({nums[i],nums[l],nums[s],nums[h]});
                    while(s<h && nums[s]==nums[s+1])
                        s++;
                    while(s<h && nums[h]==nums[h-1])
                        h--;
                        s++;
                        h--;
                }
			
		}
	}
	
}
        return res;
    }
};

js 

var fourSum = function(nums, target) {
    const quadruplets = [];
    if (nums.length < 4) {
        return quadruplets;
    }
    nums.sort((x, y) => x - y);
    const length = nums.length;
    for (let i = 0; i < length - 3; i++) {
        if (i > 0 && nums[i] === nums[i - 1]) {
            continue;
        }
        if (nums[i] + nums[i + 1] + nums[i + 2] + nums[i + 3] > target) {
            break;
        }
        if (nums[i] + nums[length - 3] + nums[length - 2] + nums[length - 1] < target) {
            continue;
        }
        for (let j = i + 1; j < length - 2; j++) {
            if (j > i + 1 && nums[j] === nums[j - 1]) {
                continue;
            }
            if (nums[i] + nums[j] + nums[j + 1] + nums[j + 2] > target) {
                break;
            }
            if (nums[i] + nums[j] + nums[length - 2] + nums[length - 1] < target) {
                continue;
            }
            let left = j + 1, right = length - 1;
            while (left < right) {
                const sum = nums[i] + nums[j] + nums[left] + nums[right];
                if (sum === target) {
                    quadruplets.push([nums[i], nums[j], nums[left], nums[right]]);
                    while (left < right && nums[left] === nums[left + 1]) {
                        left++;
                    }
                    left++;
                    while (left < right && nums[right] === nums[right - 1]) {
                        right--;
                    }
                    right--;
                } else if (sum < target) {
                    left++;
                } else {
                    right--;
                }
            }
        }
    }
    return quadruplets;
};

11.盛最多水的容器

 思想:双指针夹逼

用双指针i,j循环height数,i,j对应高度较小的那个先向内移动,不断计算面积,更新最大面积

/**
 * @param {number[]} height
 * @return {number}
 */
var maxArea = function(height) {
    const len=height.length;
    let max=0;
    for(let i=0,j=len-1;i<j;){
        let minheight=height[i]<height[j]?height[i++]:height[j--];
        let res=minheight*(j-i+1);
        max=Math.max(max,res);
    }
    return max;
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值