LeetCode热题100速通

news/2024/12/22 14:15:19/

一丶哈希

1、两数之和(简单)
给定一个整数数组 n u m s nums nums 和一个整数目标值 t a r g e t target target,请你在该数组中找出 和为目标值 t a r g e t target target 的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案,并且你不能使用两次相同的元素。
你可以按任意顺序返回答案。

示例 1:输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
示例 2:输入:nums = [3,2,4], target = 6
输出:[1,2]
示例 3:输入:nums = [3,3], target = 6
输出:[0,1]

方法一(自己想到):暴力枚举,两次循环遍历所有相加的情况

class Solution {public int[] twoSum(int[] nums, int target) {for(int i=0;i<nums.length;i++){for(int j=i+1;j<nums.length;j++){if(nums[i]+nums[j]==target){return new int[]{i,j};}}}return new int[0];}
}

方法二(想不到):哈希表,遍历数组查看哈希表中是否存在target-当前数组元素值的key,如果存在返回当前数组索引和哈希表key的value,不存在把当前的数组元素和下标记录到哈希表中

class Solution {public int[] twoSum(int[] nums, int target) {Map<Integer,Integer> map=new HashMap<>();for(int i=0;i<nums.length;i++){if(map.containsKey(target-nums[i])){return new int[]{i,map.get(target-nums[i])};}map.put(nums[i],i);}return new int[0];}
}

2、字母异位词分组(中等)
给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。

字母异位词 是由重新排列源单词的所有字母得到的一个新单词。

示例 1:输入: strs = ["eat", "tea", "tan", "ate", "nat", "bat"]
输出: [["bat"],["nat","tan"],["ate","eat","tea"]]
示例 2:输入: strs = [""]
输出: [[""]]
示例 3:输入: strs = ["a"]
输出: [["a"]]

方法一:排序(想不到)
字母异位词经过排序都是相同的,可以作为哈希表的键。然后同一个组的字母异位词组成的集合作为哈希表的值

class Solution {public  List<List<String>> groupAnagrams(String[] strs) {HashMap<String,List<String>> map=new HashMap<>();for (String s:strs) {char[] arr=s.toCharArray();Arrays.sort(arr);String key=new String(arr);List<String> list=map.getOrDefault(key,new ArrayList<>());list.add(s);map.put(key,list);}return new ArrayList<>(map.values());}
}

方法二:计数(想不到)
由于互为字母异位词的两个字符串包含的字母相同,因此两个字符串中的相同字母出现的次数一定是相同的,故可以将每个字母出现的次数使用字符串表示,作为哈希表的键。例如eat,可以表示为a1e1t1这样的形式。不过个人感觉实现起来不如方法一方便,原理其实也差不多

class Solution {public  List<List<String>> groupAnagrams(String[] strs) {HashMap<String,List<String>> map=new HashMap<>();for (String s:strs) {int[] count=new int[26];  //只有小写字母for (int i = 0; i < s.length(); i++) {count[s.charAt(i) - 'a']++;}StringBuffer sb = new StringBuffer();for (int i = 0; i < 26; i++) {if (count[i] != 0) {sb.append((char) ('a' + i));sb.append(count[i]);}}String key = sb.toString();List<String> list = map.getOrDefault(key, new ArrayList<String>());list.add(s);map.put(key, list);}return new ArrayList<>(map.values());}
}

3、最长连续序列(中等)
给定一个未排序的整数数组 nums ,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。

请你设计并实现时间复杂度为 O(n) 的算法解决此问题。

示例 1:输入:nums = [100,4,200,1,3,2]
输出:4
解释:最长数字连续序列是 [1, 2, 3, 4]。它的长度为 4。
示例 2:输入:nums = [0,3,7,2,5,8,4,6,0,1]
输出:9

方法一(想不到):哈希表
先把数组的元素存在HashSet里面。然后遍历HashSet,每当遍历到一个元素x,判断x-1是否存在hash里面,存在的话就可以直接跳过,因为我们会从x-1开始寻找最长序列。如果不存在的话,就循环去hash里找x+1,x+2,直到找到所有的。

class Solution {public  int longestConsecutive(int[] nums) {HashSet<Integer> set=new HashSet<>();for (int num:nums) {set.add(num);}int longlen=0;for (int num:set) {if(!set.contains(num-1)){int current=num;int maxlen=1;while (set.contains(current+1)){current++;maxlen++;}longlen=Math.max(longlen,maxlen);}}return longlen;}
}

二、双指针

1、 移动零(简单)
给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
请注意 ,必须在不复制数组的情况下原地对数组进行操作。

示例 1:输入: nums = [0,1,0,3,12]
输出: [1,3,12,0,0]
示例 2:输入: nums = [0]
输出: [0]

方法一(自己想到):双指针,一个指针指向0,一个指针非0,交换指针后,然后继续查找下一个零元素和非零元素。

class Solution {public  void moveZeroes(int[] nums) {int p1=0,p2=0;     //p1指向0元素,p2指向非0元素while (p1<nums.length&&p2<nums.length){while (p1<nums.length){if(nums[p1]==0){break;}p1++;}p2=p1+1;while (p2<nums.length){if(nums[p2]!=0){break;}p2++;}if(p1!=nums.length&&p2!=nums.length){int temp=nums[p1];nums[p1]=nums[p2];nums[p2]=temp;}}}
}

方法二(想不到):
快慢指针,如果数组没有0,那么快慢指针始终指向同一个位置,每个位置自己和自己交换;如果数组有0,快指针先走一步,此时慢指针对应的就是0,所以要交换。

class Solution {public void moveZeroes(int[] nums) {int n = nums.length, left = 0, right = 0;while (right < n) {if (nums[right] != 0) {swap(nums, left, right);left++;}right++;}}public void swap(int[] nums, int left, int right) {int temp = nums[left];nums[left] = nums[right];nums[right] = temp;}
}

三、滑动窗口

四、子串

五、普通数组

六、矩阵

七、链表

八丶二叉树

九、图论

十丶回溯

十一、二分查找

1、搜索插入位置(简单)
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
请必须使用时间复杂度为 O(log n) 的算法

示例 1:输入: nums = [1,3,5,6], target = 5
输出: 2
示例 2:输入: nums = [1,3,5,6], target = 2
输出: 1
示例 3:输入: nums = [1,3,5,6], target = 7
输出: 4

方法(自己想到):标准的二分查找,题目多要求了一个返回没找到值的插入位置,判断一下返回mid或者mid+1就可以

class Solution {public  int searchInsert(int[] nums, int target) {int low=0,high=nums.length-1,mid=0;while(low<=high){mid=(low+high)/2;if(nums[mid]==target)return mid;else if(nums[mid]>target)high=mid-1;else low=mid+1;}if(nums[mid]>target){return mid;}return mid+1;}
}

十二、栈

十三、堆

十四丶贪心算法

十五丶动态规划

十六丶多维动态规划

十七、技巧

1、只出现一次的数字(简单)
给你一个 非空 整数数组 nums ,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。

你必须设计并实现线性时间复杂度的算法来解决此问题,且该算法只使用常量额外空间。

示例 1 :输入:nums = [2,2,1]
输出:1
示例 2 :输入:nums = [4,1,2,1,2]
输出:4
示例 3 :输入:nums = [1]
输出:1

方法一:这个就是记住这个异或运算符^的定理就好了,任何数和0异或是本身,任何数和自身异或是0

class Solution {public int singleNumber(int[] nums) {int sum=nums[0];for(int i=1;i<nums.length;i++){sum^=nums[i];}return sum;}
}

2、多数元素(简单)
给定一个大小为 n 的数组 nums ,返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。

你可以假设数组是非空的,并且给定的数组总是存在多数元素。

示例 1:输入:nums = [3,2,3]
输出:3
示例 2:输入:nums = [2,2,1,1,1,2,2]
输出:2

方法1(自己想到):用哈希表,遍历数组把每个元素的数量存下来,然后遍历哈希表,找出数量大于数组一半的即可

class Solution {public int majorityElement(int[] nums) {HashMap<Integer,Integer> map=new HashMap<>();for(int i=0;i<nums.length;i++){if(map.containsKey(nums[i])){map.put(nums[i],map.get(nums[i])+1);}else {map.put(nums[i],1);}}for (Map.Entry<Integer,Integer> entry: map.entrySet()) {int key=entry.getKey();int value=entry.getValue();if(value>nums.length/2){return key;}}return nums[0];}
}

方法2(想不到):Boyer-Moore 投票算法
如果我们把众数记为 +1,把其他数记为 −1,将它们全部加起来,显然和大于 0,从结果本身我们可以看出众数比其他数多。

class Solution {public int majorityElement(int[] nums) {int count=0,candidate=0;for(int i=0;i<nums.length;i++){if(count==0)candidate=nums[i];if(nums[i]==candidate)count++;else count--;}return candidate;}
}

http://www.ppmy.cn/news/1533334.html

相关文章

uni-app在线预览pdf

这里推荐下载pdf.js 插件 PDF.js - Browse Files at SourceForge.net 特此注意 如果报 Promise.withResolvers is not a function 请去查看版本兼容问题 降低pdf.js版本提高node版本 下载完成后 在 static 文件夹下新建 pdf 文件夹&#xff0c;将解压文件放进 pdf 文件…

十三、减少磁盘延迟时间的方法

1.交替编号 让逻辑上相邻的扇区在物理上不相邻&#xff1b; 原因&#xff1a;由于磁头在读取完一个扇区之后需要等待一段时间才能再次读入下一个扇区&#xff0c;如果逻辑上相邻的扇区在物理上相邻的话&#xff0c;需要等待磁盘转完一圈才能读取到。 2.错位命名 让相邻盘面上…

Javascript-标准内置对象-值属性-globalThis-Infinity-Nan-undefined 手写实现globalThis功能

1 globalThis 1.1 globalThis简介 globalThis 是 ECMAScript 2020&#xff08;ES11&#xff09;引入的全局对象的标准化引用。在不同JavaScript 运行环境中&#xff0c;全局对象的名称可能不同&#xff1a; 浏览器中是 window。 Node.js 中是 global。 Web Workers 中是 self。…

Spring Boot 集成 MySQL 的详细指南

在现代软件开发中&#xff0c;Spring Boot 因其简单易用而成为构建 Java 应用程序的热门选择。结合 MySQL这一常用关系型数据库&#xff0c;开发者可以快速构建出功能完善的后端服务。本文将详细介绍如何将 Spring Boot 与 MySQL 集成&#xff0c;提供从环境搭建到代码实现的全…

【前端安全】js逆向之微信公众号登录密码

❤️博客主页&#xff1a; iknow181 &#x1f525;系列专栏&#xff1a; 网络安全、 Python、JavaSE、JavaWeb、CCNP &#x1f389;欢迎大家点赞&#x1f44d;收藏⭐评论✍ 随着发展&#xff0c;越来越多的登录页面添加了密码加密的措施&#xff0c;使得暴力破解变得不在简单&a…

微软开源GraphRAG的使用教程-使用自定义数据测试GraphRAG

微软在今年4月份的时候提出了GraphRAG的概念&#xff0c;然后在上周开源了GraphRAG,Github链接见https://github.com/microsoft/graphrag,截止当前&#xff0c;已有6900Star。 安装教程 官方推荐使用Python3.10-3.12版本&#xff0c;我使用Python3.10版本安装时&#xff0c;在…

Spring Boot 调用外部接口的常用方式!

使用Feign进行服务消费是一种简化HTTP调用的方式&#xff0c;可以通过声明式的接口定义来实现。下面是一个使用Feign的示例&#xff0c;包括设置Feign客户端和调用服务的方法。 添加依赖 首先&#xff0c;请确保你的项目中已经添加了Feign的依赖。如果你使用的是Maven&#xf…

【QT】QWidget 重要属性

文章目录 enabledgeometrywindowTitlewindowIconqrc 机制windowOpacitycursorfontQFont toolTip 和 toolTipDurationfocusPolicyQt::FocusPolicy styleSheet enabled 作用&#xff1a;设置控件是否可使用. true 表⽰可用, false 表⽰禁用. 对应的API bool isEnabled(); // 获…