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

【leetcode hot 100 15】三数之和

一、两数之和的扩展

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        // 将得到的结果存入Set中,保证不重复
        Set<List<Integer>> set = new HashSet<>();

        // 模拟两数之和,作为第一个循环中的内容
        for(int i=0; i<nums.length; i++){
            // 用map来存<complement,id>键值对
            Map<Integer,Integer> map = new HashMap<>();
            for(int j=i+1; j<nums.length; j++){
                int complement = -nums[i]-nums[j];
                if(map.containsKey(complement)){
                    // 满足要求
                    Integer[] tmp = new Integer[]{nums[i],nums[j],complement};
                    Arrays.sort(tmp);  // 排序 避免重复
                    set.add(Arrays.asList(tmp));
                }
                map.put(nums[j],j);
            }
        }

        return new ArrayList<>(set);
    }
}

注意:

  • 关于数组的操作在Arrays(注意有s)中,例如:排序Arrays.sort(tmp)->tmp直接变,无需返回值
  • 数组与集合相互转换:Arrays.asList()(数组->list) list.toArray()(list->数组)
  • 集合与集合相互转换:new ArrayList<>(set)(set->list) new HashSet<>(list)(list->set)

错误原因:超出时间限制

在这里插入图片描述

双指针解法:先用一个 for 循环遍历数组,对于每个数字,使用双指针在数组的剩余部分查找和为 0 的另外两个元素。

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        // 先申请一个list
        List<List<Integer>> res = new LinkedList<>();
        // 排序nums,便于消除重复的数
        Arrays.sort(nums);
        // 循环每一个num,在后面用两个指针找满足需求的数
        for(int i=0; i<nums.length-2; i++){
            // 这里nums.length-2,因为后面还需要提取两个数->提高效率
            int left=i+1, right=nums.length-1, complement=-nums[i];
            if(i==0 || i>0 && nums[i]!=nums[i-1]){
                // 要保证nums[i]是第一个不一样的数,避免重复
                while(left<right){
                    // 循环寻找两个数
                    if(complement == nums[right]+nums[left]){
                        // 找到三个数
                        Integer[] tmp=new Integer[]{nums[i],nums[right],nums[left]};
                        res.add(Arrays.asList(tmp));

                        // 保证后面两个数再次取到的数不重复 
                        while(left<right && nums[left]==nums[left+1]){left++;}
                        while(left<right && nums[right]==nums[right-1]){right--;}
                        left++;
                        right--;
                    }
                    else if(complement > nums[right]+nums[left]){
                        // 要一个大一点的数
                        left++;
                    }
                    else{
                        // 要一个小一点的数
                        right--;
                    }
                }
            }
        }
        return res;
    }
}

注意:

  • LinkedList中有ed;不存在HashlList
  • if(complement == nums[right]+nums[left])判断后,还要判断if(complement > nums[right]+nums[left]),确保后面有
  • for内还有while循环,用于循环后面两个数
  • Arrays.asList(1,2,3); or Integer[] tmp = new Integer[]{1,2,3}; Arrays.asList(tmp);

相关文章:

  • StableDiffusion本地部署 2
  • TCP的三次握手与四次挥手:建立与终止连接的关键步骤
  • pta天梯L1-003 个位数统计
  • 点云配准技术的演进与前沿探索:从传统算法到深度学习融合(3)
  • Linux上用C++和GCC开发程序实现不同MySQL实例下单个Schema之间的稳定高效的数据迁移
  • Android应用app实现AI电话机器人接打电话
  • 【杂谈】-2025年2月五大大型语言模型(LLMs)
  • 有没有比黑暗森林更黑暗的理论
  • YOLO 检测到人通俗易懂的原理
  • AnythingLLM+LM Studio本地知识库构建
  • kotlin的函数标准库使用
  • python-leetcode-不同路径
  • 基于 Flink CDC YAML 的 MySQL 到 Kafka 流式数据集成
  • 【一起学Rust | Tauri2.0框架】单实例应用程序的深入解析:零漏洞实现与优化实战
  • SpringBoot 整合mongoDB并自定义连接池,实现多数据源配置
  • 【软考】【2025年系统分析师拿证之路】【啃书】第十四章 软件实现与测试(十五)
  • 进阶面试题 ——‘说说你对浏览器的V8引擎的理解’
  • python开发之 __init__.py的一些基本用法
  • C高级(shell)
  • C高级----shell作业
  • 张涌任西安市委常委,已卸任西安市副市长职务
  • 小米SU7 Ultra风波升级:数百名车主要求退车,车主喊话雷军“保持真诚”
  • 2025年上海好护士揭晓,上海护士五年增近两成达12.31万人
  • 专访|日本驻华大使金杉宪治:对美、对华外交必须在保持平衡的基础上稳步推进
  • 默茨首访聚焦欧洲,欲推欧洲防务自主
  • 宝妈称宝宝在粽子中吃出带血创可贴,来伊份:已内部排查