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

牛客算法_哈希

1. 两数之和

思路:

1. map, key存放数组元素,value存放下标位置

2. 如果key重复,记录最小的下标

3. 遍历map, target-当前map位置的值, 判断差x在map中的位置

        3.1 当前map位置的值 = x,  找到下一个=x的位置

        3.2 当前map位置的值 != x, 直接从map中定位到下标

注意:HashMap放入元素的顺序,和map.keySet()的顺序不一致, 改成LinkedHashMap(遍历顺序与插入顺序一致)

  • TreeMap(按key排序)
  • 自定义排序的 TreeMap
// 按key长度排序
Map<String, Integer> map = new TreeMap<>(Comparator.comparing(String::length).thenComparing(String::compareTo)
);

    public int[] twoSum (int[] numbers, int target) {if(numbers == null || numbers.length <= 0){return null;}LinkedHashMap<Integer, Integer> map = new LinkedHashMap();for(int i = 0; i < numbers.length; i++){if(map.get(numbers[i]) == null){map.put(numbers[i], i+1);}}for(Integer key : map.keySet()){int x = target - key;int index = map.get(key);if(map.get(x) != null && map.get(x) != index){int[] res = new int[2];res[0] = index;res[1] = map.get(x);return res;}if(map.get(x) != null && map.get(x) == index){int[] res = new int[2];res[0] = index;int secondIndex = findSecondVal(numbers, index, x);if(secondIndex == -1){continue;}else{res[1] = secondIndex;return res;}}}return null;}private int findSecondVal(int[] numbers, int  beginIndex, int findVal) {for(int i = beginIndex; i < numbers.length; i++){if(numbers[i] == findVal){return i+1;}}return -1;}

2. 数组中次数超过一半的数字

  public int MoreThanHalfNum_Solution(int[] numbers) {if(numbers == null || numbers.length <= 0){return -1;}int halfLength =  numbers.length / 2;HashMap<Integer, Integer> map = new HashMap();for (int i = 0; i < numbers.length; i++) {if (map.get(numbers[i]) == null) {map.put(numbers[i], 1);} else {map.put(numbers[i], map.get(numbers[i]) + 1);}if (map.get(numbers[i]) > halfLength) {return numbers[i];}}return -1;}

3. 数组中只出现一次的两个数字

一个整型数组里除了两个数字只出现一次,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。

思路:因为条件限制比较完美(数字要么出现1次 要么2次),所以下面的做法满足要求。

注意:结束TreeMap 保证key的顺序

public int[] FindNumsAppearOnce (int[] nums) {if(nums == null || nums.length <= 0){return null;}TreeMap<Integer, Integer> map = new TreeMap<Integer, Integer>();for(int i = 0; i < nums.length; i++){if(map.get(nums[i]) == null){map.put(nums[i], i);}else{map.remove(nums[i]);}}int index = 0;int[] res = new int[2];for(Integer key : map.keySet()){res[index++] = key;}return res;}

4. 缺失的最小的正整数

 public int minNumberDisappeared(int[] nums) {if (nums == null || nums.length <= 0) {return -1;}HashMap<Integer, Integer> map = new HashMap();for (int i = 0; i < nums.length; i++) {if (nums[i] > 0) {map.put(nums[i], 1);}}for (int i = 1; i < Integer.MAX_VALUE; i++) {if (map.get(i) == null) {return i;}}return -1;}

5. 三数之和(重点)

思路:

  1. 先对数组进行排序,这样便于去重和控制遍历顺序

  2. 固定第一个数,然后在剩余部分使用双指针寻找另外两个数

  3. 通过跳过重复元素来避免重复的三元组

步骤:

  1. 对数组进行排序

  2. 遍历数组,将当前元素作为第一个数 nums[i]

  3. 如果 nums[i] > 0,由于数组已排序,后面的数都更大,不可能和为0,直接结束

  4. 如果当前元素与前一个相同,跳过以避免重复

  5. 使用双指针 leftrighti+1n-1 的范围内寻找另外两个数

  6. 根据三数之和调整指针位置

  public ArrayList<Integer> generateList(int x, int y, int w) {ArrayList<Integer> list = new ArrayList<Integer>();list.add(x);list.add(y);list.add(w);return list;}public ArrayList<ArrayList<Integer>> threeSum2(int[] nums) {ArrayList<ArrayList<Integer>> result = new ArrayList<ArrayList<Integer>>();// 边界情况处理if (nums == null || nums.length < 3) {return result;}// 排序数组Arrays.sort(nums);int n = nums.length;for (int i = 0; i < n - 2; i++) {// 如果第一个数大于0,后面的数都更大,不可能和为0if (nums[i] > 0) {break;}// 跳过重复的第一个数if (i > 0 && nums[i] == nums[i - 1]) {continue;}int left = i + 1;int right = n - 1;while (left < right) {int sum = nums[i] + nums[left] + nums[right];if (sum == 0) {// 找到满足条件的三元组result.add(generateList(nums[i], nums[left], nums[right]));// 跳过重复的leftwhile (left < right && nums[left] == nums[left + 1]) {left++;}// 跳过重复的rightwhile (left < right && nums[right] == nums[right - 1]) {right--;}// 移动指针继续寻找left++;right--;} else if (sum < 0) {// 和太小,需要增大,移动左指针left++;} else {// 和太大,需要减小,移动右指针right--;}}}return result;}

http://www.dtcms.com/a/457293.html

相关文章:

  • Product Hunt 每日热榜 | 2025-10-08
  • 重庆建站公司官网国外有名的网站
  • 【论文阅读】Visual Planning: Let’s Think Only with Images
  • 河南教育平台网站建设为中小型企业构建网站
  • 开放指令编辑创新突破!小米开源 Lego-Edit 登顶 SOTA:用强化学习为 MLLM 编辑开辟全新赛道!
  • Vue 与 React 深度对比:底层原理、开发体验与实际性能
  • 平台网站建设协议电话网站域名到期
  • Spring Gateway 全面解析:从入门到进阶实践​
  • 江西九江网站建设注册登记
  • 建个微网站多少钱tv网站建设
  • Docker 说明与安装
  • Docker 镜像结构与相关核心知识总结
  • 容器技术与 Docker 入门部署
  • linux学习笔记(20)线程
  • Vue3后台表单快速开发
  • 前端技术栈 —— 创建React项目
  • 推荐一个 GitHub 开源项目信息卡片生成工具,支持Docker快速部署和API调用
  • 元宇宙的工业制造应用:重构生产、研发与供应链
  • 做美足网站违法吗北京网站建设哪家比较好
  • 2025版本的idea解决Git冲突
  • 深入浅出 HarmonyOS ArkTS:现代跨平台应用开发的语法基石
  • Spring boot 3.0整合RocketMQ不兼容的问题
  • 淮安制作企业网站莱芜金点子最新招聘
  • AI+机器人浪潮已至:是方舟还是巨浪?
  • Linux:虚拟世界的大门
  • 市桥网站建设培训数据库与网站建设
  • LangGraph学习笔记 (二)-10分钟搭建自己第一个Agent
  • Sutton:LLM 通往 AGI 的隐秘瓶颈
  • 吴恩达机器学习课程(PyTorch 适配)学习笔记大纲
  • 聊透自动驾驶系统:从“怎么跑”到“怎么聪明跑”