两数之和
给定一个整数数组 nums
和一个整数目标值 target
,请你在该数组中找出和为目标值 target
的那两个整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案。
class Solution{
public int[] two_sum(int[] nums,int target){
Map<Integer,Integer> map = new HashMap<>();
for(int i=0;i<nums.length,++i){
diff = target - nums[i];
if(map.containKey(diff)) {
return new int[]{i,map.get(diff)}
}
map.put(nums[i],i);
}
return null;
}
}
字母异位词分组
给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。
字母异位词 是由重新排列源单词的所有字母得到的一个新单词。
- 方法1
异位词按照字母顺序做排序后一定相等,所以对每一个词利用Array.sort进行排序,结果作为key,value为一个列表,存放排序后为当前key的所有词
class Solution {
public List<List<String>> groupAnagrams(String[] strs) {
Map<String, List<String>> map = new HashMap<>();
for (String str : strs) {
char[] chars = str.toCharArray();
Arrays.sort(chars);
String sort_str = new String(chars);
if(map.containsKey(sort_str)){
map.get(sort_str).add(str);
}else{
List list = new ArrayList<>();
list.add(str);
map.put(sort_str,list);
}
}
return new ArrayList<>(map.values());
}
}
- 方法2
字母异位词的原料一定相同,所以可以利用一个类来描述该词,即利用一个数组来存储该词的每一个字母的个数。该类可以替代方法1的key。
注意:一定要要重写equals和hashcode方法!
此方法无需对字符串进行排序,而是遍历累加,所以时间复杂度上会更优秀。
class Solution {
public List<List<String>> groupAnagrams(String[] strs) {
Map<Word, List<String>> map = new HashMap<>();
for (String str : strs) {
Word word = new Word(str);
if(map.containsKey(word)){
map.get(word).add(str);
}else{
List list = new ArrayList<>();
list.add(str);
map.put(word,list);
}
}
return new ArrayList<>(map.values());
}
class Word{
private char[] chars = new char[26];
Word(String s){
char[] chars1 = s.toCharArray();
for (char c: chars1) {
chars[c-'a']++;
}
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Word word = (Word) o;
return Arrays.equals(chars, word.chars);
}
@Override
public int hashCode() {
return Arrays.hashCode(chars);
}
}
}
#最长连续序列
给定一个未排序的整数数组 nums(数据可重复)找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。
请你设计并实现时间复杂度为 O(n) 的算法解决此问题。
方法:将所有元素都放进哈希表中,key是唯一标识即可(所以用hashset即可),value即为元素值,然后遍历该哈希表,假如当前遍历值为v,若哈希表中不存在v-1,则证明它是连续序列的开头,则从它开始循环查找是否存在v+1,v+2…,若存在则将当前的序列长度+1,否则跳出循环,继续遍历哈希表。
class Solution {
public int longestConsecutive(int[] nums) {
HashSet<Integer> hashset = new HashSet<>();
for (int i = 0; i < nums.length; i++) {
hashset.add(nums[i]);
}
int count = 0;
int res = 0;
for (int v: hashset) {
if(!hashset.contains(v-1)){
count = 1;
int current = v;
while(hashset.contains(current+1)){
count++;
current++;
}
res = Math.max(count,res);
}
}
return res;
}
}
总结
哈希表主要利用空间换时间的思想
在题目中也要注意数据规模的提示# 两数之和
给定一个整数数组 nums
和一个整数目标值 target
,请你在该数组中找出和为目标值 target
的那两个整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案。
class Solution{
public int[] two_sum(int[] nums,int target){
Map<Integer,Integer> map = new HashMap<>();
for(int i=0;i<nums.length,++i){
diff = target - nums[i];
if(map.containKey(diff)) {
return new int[]{i,map.get(diff)}
}
map.put(nums[i],i);
}
return null;
}
}
字母异位词分组
给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。
字母异位词 是由重新排列源单词的所有字母得到的一个新单词。
- 方法1
异位词按照字母顺序做排序后一定相等,所以对每一个词利用Array.sort进行排序,结果作为key,value为一个列表,存放排序后为当前key的所有词
class Solution {
public List<List<String>> groupAnagrams(String[] strs) {
Map<String, List<String>> map = new HashMap<>();
for (String str : strs) {
char[] chars = str.toCharArray();
Arrays.sort(chars);
String sort_str = new String(chars);
if(map.containsKey(sort_str)){
map.get(sort_str).add(str);
}else{
List list = new ArrayList<>();
list.add(str);
map.put(sort_str,list);
}
}
return new ArrayList<>(map.values());
}
}
- 方法2
字母异位词的原料一定相同,所以可以利用一个类来描述该词,即利用一个数组来存储该词的每一个字母的个数。该类可以替代方法1的key。
注意:一定要要重写equals和hashcode方法!
此方法无需对字符串进行排序,而是遍历累加,所以时间复杂度上会更优秀。
class Solution {
public List<List<String>> groupAnagrams(String[] strs) {
Map<Word, List<String>> map = new HashMap<>();
for (String str : strs) {
Word word = new Word(str);
if(map.containsKey(word)){
map.get(word).add(str);
}else{
List list = new ArrayList<>();
list.add(str);
map.put(word,list);
}
}
return new ArrayList<>(map.values());
}
class Word{
private char[] chars = new char[26];
Word(String s){
char[] chars1 = s.toCharArray();
for (char c: chars1) {
chars[c-'a']++;
}
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Word word = (Word) o;
return Arrays.equals(chars, word.chars);
}
@Override
public int hashCode() {
return Arrays.hashCode(chars);
}
}
}
#最长连续序列
给定一个未排序的整数数组 nums(数据可重复)找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。
请你设计并实现时间复杂度为 O(n) 的算法解决此问题。
方法:将所有元素都放进哈希表中,key是唯一标识即可(所以用hashset即可),value即为元素值,然后遍历该哈希表,假如当前遍历值为v,若哈希表中不存在v-1,则证明它是连续序列的开头,则从它开始循环查找是否存在v+1,v+2…,若存在则将当前的序列长度+1,否则跳出循环,继续遍历哈希表。
class Solution {
public int longestConsecutive(int[] nums) {
HashSet<Integer> hashset = new HashSet<>();
for (int i = 0; i < nums.length; i++) {
hashset.add(nums[i]);
}
int count = 0;
int res = 0;
for (int v: hashset) {
if(!hashset.contains(v-1)){
count = 1;
int current = v;
while(hashset.contains(current+1)){
count++;
current++;
}
res = Math.max(count,res);
}
}
return res;
}
}
总结
哈希表主要利用空间换时间的思想
在题目中也要注意数据规模的提示