当前位置: 首页 > article >正文

rust学习笔记13-18. 四数之和

上一篇已经说到了两数之和,索性将三数之和与四数之和一起都复习一下

15. 三数之和

给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != ji != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请你返回所有和为 0 且不重复的三元组。

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

示例 1:

输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]
解释:
nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0 。
nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0 。
nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0 。
不同的三元组是 [-1,0,1] 和 [-1,-1,2] 。
注意,输出的顺序和三元组的顺序并不重要。

示例 2:

输入:nums = [0,1,1]
输出:[]
解释:唯一可能的三元组和不为 0 。

示例 3:

输入:nums = [0,0,0]
输出:[[0,0,0]]
解释:唯一可能的三元组和为 0 。

提示:

  • 3 <= nums.length <= 3000
  • -105 <= nums[i] <= 105

解答 

//双指针
pub fn three_sum(nums: Vec<i32>) -> Vec<Vec<i32>> {

    let mut resultList:Vec<Vec<i32>> =Vec::new();
    let mut nums2 = nums.clone();
    // 先进行排序
    nums2.sort();
    for i in 0..nums2.len() {
        // 如果最小的都大于0,那就没有集合,直接返回
        if nums2[i] > 0 {
            return resultList;
        }
        // 去重
        if i > 0 && nums2[i] == nums2[i - 1] {
            continue;
        }
        
        let mut  left = i + 1;
        let mut  rigth = nums2.len() - 1;
        while left < rigth {
            let n = nums2[i] + nums2[left] + nums2[rigth];
            if n > 0 {
                rigth -= 1;
            }else if  n < 0  {
                left += 1; 
            }else {
                resultList.push(vec![nums2[i],nums2[left],nums2[rigth]]);
                //右侧去重
                while left < rigth && nums2[rigth] == nums2[rigth - 1] {
                    rigth -= 1;
                }
                //左侧去重
                while left < rigth && nums2[left] == nums2[left + 1] {
                    left += 1;
                }
                rigth -= 1;
                left += 1; 
            }  
        }
    }

    return  resultList;
        
}


//三数之和
fn main() {
    let nums = vec![-1,0,1,2,-1,-4];
    let res = three_sum(nums);
    println!("{:?}", res);
}

18. 四数之和

给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] (若两个四元组元素一一对应,则认为两个四元组重复):

  • 0 <= a, b, c, d < n
  • abc 和 d 互不相同
  • nums[a] + nums[b] + nums[c] + nums[d] == target

你可以按 任意顺序 返回答案 。

示例 1:

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

示例 2:

输入:nums = [2,2,2,2,2], target = 8
输出:[[2,2,2,2]]

提示:

  • 1 <= nums.length <= 200
  • -109 <= nums[i] <= 109
  • -109 <= target <= 109

 四数之和与三数之和一样,无非多了一层循环,具体解法如下


pub fn four_sum(nums: Vec<i32>, target: i32) -> Vec<Vec<i32>> {
    let mut resultList:Vec<Vec<i32>> =Vec::new();
    let mut nums2 = nums.clone();
    // 先进行排序
    nums2.sort();
    for i in 0..nums2.len() {
        //剪枝
        if nums2[i] > target && nums2[i] >= 0 {
            break;
        }

        // 第一层去重
        if i > 0 && nums2[i] == nums2[i - 1] {
            continue;
        }

        for j in  i+1..nums2.len() {
            // 解释一下,i=nums[0], j=nums[1], left=nums[2], rigth=nums[3]
            // 第二层剪枝
            if nums2[i] + nums2[j] > target && nums2[i] + nums2[j] >= 0 {
                break;
            }
            // 第二层去重
            if j > i + 1 && nums2[j] == nums2[j - 1] {
                continue;
            }

            let mut  left = j + 1;
            let mut  rigth = nums2.len() - 1;
            while left < rigth {
                let n: i32 = nums2[i] + nums2[j] + nums2[left] + nums2[rigth];
                if n > target {
                    rigth -= 1;
                }else if  n < target  {
                    left += 1; 
                }else {
                    resultList.push(vec![nums2[i], nums2[j], nums2[left],nums2[rigth]]);
                    //右侧去重
                    while left < rigth && nums2[rigth] == nums2[rigth - 1] {
                        rigth -= 1;
                    }
                    //左侧去重
                    while left < rigth && nums2[left] == nums2[left + 1] {
                        left += 1;
                    }
                    rigth -= 1;
                    left += 1; 
                }  
            }
        }

    }

    return resultList;
        
}
fn main() {
    let nums = vec![1,0,-1,0,-2,2];
    let res = four_sum(nums, 0);
    println!("{:?}", res);
}

总结,两数之和与三数之和、四数之和解法不一样,主要是因为返回值,两数之和要返回下角标不能做排序,用hashmap合适,而三数之和、四数之和是要求返回结果集且不能重复,需要对数组进行排序,用双指针更适合。


http://www.kler.cn/a/583077.html

相关文章:

  • 【Spring】@PostConstruct详解
  • Conda:CondaSSLError
  • LabVIEW VI Scripting实现连接器窗格自动化
  • varchar (255) varchar (2550) 在mysql中实际占的空间会是十倍吗
  • MySQL的安装、备份还原及主从同步
  • java设计模式之桥接模式
  • 深度学习GRU模型原理
  • Linux——Shell运行原理以及Linux权限
  • 【Linux docker 容器】关于想要让虚拟机在开机时候也docker自己启动,容器也自己启动,省去要自己开docker和容器
  • 已安装 MFC 仍提示“此项目需要 MFC 库”的解决方法 (MSB8041)
  • 骑士74CMS_v3.34.0SE版uniapp全开源小程序怎么编译admin和member流程一篇文章说清楚
  • 【Go语言圣经1.5】
  • 前端对话框项目——调用字节Coze API
  • 18 | 实现简洁架构的 Handler 层
  • python str repr方法区别
  • 数据库原理4
  • 开源链动2+1模式AI智能名片S2B2C商城小程序在KOC参与门店做透中的应用探索
  • 本地部署资源聚合搜索神器 Jackett 并实现外部访问
  • 苹果“被盗设备保护”的取证意义
  • Haproxy配置入门