目录
七、leetcode347:Top K Frequent Elements
八、350:Intersection-of-Two-Arrays(II)
一、leetcode 290. 单词规律
1.题目描述
给定一种规律 pattern
和一个字符串 str
,判断 str
是否遵循相同的规律。
这里的 遵循 指完全匹配,例如, pattern
里的每个字母和字符串 str
中的每个非空单词之间存在着双向连接的对应规律。
示例1:
输入: pattern ="abba"
, str ="dog cat cat dog"
输出: true
示例 2:
输入:pattern ="abba"
, str ="dog cat cat fish"
输出: false
示例 3:
输入: pattern ="aaaa"
, str ="dog cat cat dog"
输出: false
示例 4:
输入: pattern ="abba"
, str ="dog dog dog dog"
输出: false
2.题目分析:
采用两个Map,值都存储位置信息index,
其中Map1的key为字符,Map2的key为字符串。
通过put和get方法来进行添加和查询位置,以判断是否符合相同的规则。
3.代码:
public class Solution290 {
public boolean wordPattern(String pattern, String str) {
String[] strings = str.split(" ");
if(strings.length!=pattern.length())return false;
Map<Character,Integer> map1 = new HashMap<>();
Map<String,Integer> map2 = new HashMap<>();
for(int i=0;i<strings.length;i++){
if (!map1.containsKey(pattern.charAt(i))) {
map1.put(pattern.charAt(i), i);
}
if (!map2.containsKey(strings[i])) {
map2.put(strings[i], i);
}
int a=map1.get(pattern.charAt(i));
int b=map2.get(strings[i]);
if(a!=b){
return false;
}
}
return true;
}
public static void main(String[] args) {
String pattern= "abba";
String str="dog cat cat fish";
Solution290 solution290 = new Solution290();
boolean result=solution290.wordPattern(pattern,str);
System.out.println(result);
}
}
二、leetcode 205. 同构字符串
难度简单
1.题目描述
给定两个字符串 s 和 t,判断它们是否是同构的。
如果 s 中的字符可以被替换得到 t ,那么这两个字符串是同构的。
所有出现的字符都必须用另一个字符替换,同时保留字符的顺序。两个字符不能映射到同一个字符上,但字符可以映射自己本身。
示例 1:
输入: s ="egg",
t ="add"
输出: true
示例 2:
输入: s ="foo",
t ="bar"
输出: false
示例 3:
输入: s ="paper",
t ="title"
输出: true
2.分析:同上一题类似
class Solution {
public boolean isIsomorphic(String s, String t) {
char [] strings1 = s.toCharArray();
char [] strings2 = t.toCharArray();
if(strings1.length!=strings2.length)return false;
Map<Character,Integer> map1 = new HashMap<>();
Map<Character,Integer> map2 = new HashMap<>();
for(int i=0;i<strings1.length;i++){
if (!map1.containsKey(strings1[i])) {
map1.put(strings1[i], i);
}
if (!map2.containsKey(strings2[i])) {
map2.put(strings2[i], i);
}
int a=map1.get(strings1[i]);
int b=map2.get(strings2[i]);
if(a!=b){
return false;
}
}
return true;
}
}
三、leetcode 451. 根据字符出现频率排序
难度中等
1.题目描述
给定一个字符串,请将字符串里的字符按照出现的频率降序排列。
示例 1:
输入:
"tree"
输出:
"eert"
解释:
'e'出现两次,'r'和't'都只出现一次。
因此'e'必须出现在'r'和't'之前。此外,"eetr"也是一个有效的答案。
示例 2:
输入:
"cccaaa"
输出:
"cccaaa"
解释:
'c'和'a'都出现三次。此外,"aaaccc"也是有效的答案。
注意"cacaca"是不正确的,因为相同的字母必须放在一起。
示例 3:
输入:
"Aabb"
输出:
"bbAa"
解释:
此外,"bbaA"也是一个有效的答案,但"Aabb"是不正确的。
注意'A'和'a'被认为是两种不同的字符。
2.分析
1.使用一个数组存储结果,下标代表字符的ASCII码,值存储pair
2.定义Pair类,包含频率和字符,两个元素
3.自定义Conparator,按照频率从大到小排序
package IMUHERO;
import java.util.Arrays;
import java.util.Comparator;
public class Solution451{
public String frequencySort(String s) {
Pair [] arr=new Pair[256];//定义一个数组,下标代表字符下标,值存储pair
//初始化数组
for (int i=0;i<256;i++){
arr[i]=new Pair(0,(char)i);
}
//增加指定字符的频率
for (int j=0;j<s.length();j++){
arr[s.charAt(j)].fre++;
}
//频率高的往前排
Arrays.sort(arr,new myCompare());
StringBuffer str=new StringBuffer();
for (int k=0;k<s.length();k++){
if (arr[k].fre==0)break;
//输出Pair中存储的所有字符
while (arr[k].fre!=0) {
str.append(arr[k].c);
arr[k].fre--;
}
}
return str.toString();
}
}
//自定义Comparator排序规则是按照频率,从大到小
class myCompare implements Comparator<Pair> {
@Override
public int compare(Pair o1, Pair o2) {
return o2.fre-o1.fre;
}
}
//自定义封装类,用于存储频率和字符
class Pair{
public int fre;
public char c;
Pair(int fre,char c){
this.fre=fre;
this.c=c;
}
}
四、leetcode 219. 存在重复元素 II
难度简单
1.题目描述
给定一个整数数组和一个整数 k,判断数组中是否存在两个不同的索引 i 和 j,使得 nums [i] = nums [j],并且 i 和 j 的差的绝对值最大为 k。
示例 1:
输入: nums = [1,2,3,1], k = 3
输出: true
示例 2:
输入: nums = [1,0,1,1], k = 1
输出: true
示例 3:
输入: nums = [1,2,3,1,2,3], k = 2
输出: false
2.分析
1.使用map存储下标和值
2.先判断值是否相等、再判断下标间距是否<=k,即可得出正确结果
class Solution {
public boolean containsNearbyDuplicate(int[] nums, int k) {
TreeMap<Integer,Integer> map=new TreeMap<>();
for(int i=0;i<nums.length;i++){
if(map.containsKey(nums[i])){
if(i-map.get(nums[i])<=k)return true;
}
map.put(nums[i],i);
}
return false;
}
}
五、 leetcode 220. 存在重复元素 III
桶排序!!!
难度中等
1.题目描述
给定一个整数数组,判断数组中是否有两个不同的索引 i 和 j,使得 nums [i] 和 nums [j] 的差的绝对值最大为 t,并且 i 和 j 之间的差的绝对值最大为 ķ。
示例 1:
输入: nums = [1,2,3,1], k = 3, t = 0
输出: true
示例 2:
输入: nums = [1,0,1,1], k = 1, t = 2
输出: true
示例 3:
输入: nums = [1,5,9,1,5,9], k = 2, t = 3
输出: false
2.分析:使用桶排序
public class Solution220 {
// Get the ID of the bucket from element value x and bucket width w
// In Java, `-3 / 5 = 0` and but we need `-3 / 5 = -1`.
private long getID(long x, long w) {
return x < 0 ? (x + 1) / w - 1 : x / w;
}
public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) {
if (t < 0) return false;
Map<Long, Long> d = new HashMap<>();
long w = (long)t + 1;
for (int i = 0; i < nums.length; ++i) {
long m = getID(nums[i], w);
// check if bucket m is empty, each bucket may contain at most one element
if (d.containsKey(m))
return true;
// check the nei***or buckets for almost duplicate
if (d.containsKey(m - 1) && Math.abs(nums[i] - d.get(m - 1)) < w)
return true;
if (d.containsKey(m + 1) && Math.abs(nums[i] - d.get(m + 1)) < w)
return true;
// now bucket m is empty and no almost duplicate in nei***or buckets
d.put(m, (long)nums[i]);
if (i >= k) d.remove(getID(nums[i - k], w));
}
return false;
}
}
六、 leetcode 49. 字母异位词分组
难度中等
1.题目描述
给定一个字符串数组,将字母异位词组合在一起。字母异位词指字母相同,但排列不同的字符串。
示例:
输入: ["eat", "tea", "tan", "ate", "nat", "bat"]
,
输出:
[
["ate","eat","tea"],
["nat","tan"],
["bat"]
]
2.分析
1.对字符串进行内部排序,这样异位词的KEY就会相同;
2.将相同KEY的字符串存储进一个MAP中,键为字符串,值为一个字符串链表
3.最后将MAP的VALUE:所有的链表放进二维List中,并作为结果返回
class Solution {
public List<List<String>> groupAnagrams(String[] strs) {
HashMap<String,List<String>> map = new HashMap<>();
for (String s:strs){
char [] c = s.toCharArray();
Arrays.sort(c);
String key = String.valueOf(c);
if (!map.containsKey(key))map.put(key,new LinkedList<>());
map.get(key).add(s);
}
List<List<String>> ret = new LinkedList(map.values());
return ret;
}
}
七、leetcode347:Top K Frequent Elements
一、题目要求:
347. 前K个高频元素
给定一个非空的整数数组,返回其中出现频率前 k 高的元素。
示例 1:
-
输入: nums = [1,1,1,2,2,3], k = 2
-
输出: [1,2]
示例 2:
-
输入: nums = [1], k = 1
-
输出: [1]
说明:
- 你可以假设给定的 k 总是合理的,且 1 ≤ k ≤ 数组中不相同的元素的个数。
- 你的算法的时间复杂度必须优于 O(n log n) , n 是数组的大小。
二、简单分析
1.本题可以基于映射(map)实现对不同数据出现频次的存储;
2.实现一个最小堆的优先队列,将前K个优先级较高的元素存入优先队列,小于第K个元素的出队;
3.将优先队列中k个元素的数据存入LinkedlList中,提交给leetcode,即可完成任务!
三、代码实现
package IMUHERO;
/// 347. Top K Frequent Elements
/// https://leetcode.com/problems/top-k-frequent-elements/description/
import java.util.*;
public class Solution2 {
private class Freq{
public int e,freq;
public Freq(int e ,int freq){
this.e=e;
this.freq=freq;
}
}
private class FreqComparetor implements Comparator<Freq>{
@Override
public int compare(Freq a,Freq b){
return a.freq-b.freq;
}
}
public List<Integer> topKFrequent(int[] nums, int k) {
TreeMap<Integer,Integer> map=new TreeMap<>();
for (int num:nums){
if (map.containsKey(num)){
map.put(num,map.get(num)+1);
}
else{
map.put(num,1);
}
}
PriorityQueue<Freq> pQ=new PriorityQueue<>(new FreqComparetor());
for (int key:map.keySet()){
if (pQ.size()<k){
pQ.add(new Freq(key,map.get(key)));
}
else if (map.get(key)>pQ.peek().freq){
pQ.remove();
pQ.add(new Freq(key,map.get(key)));
}
}
LinkedList<Integer> res=new LinkedList<>();
while (!pQ.isEmpty()){
res.add(pQ.remove().e);
}
return res;
}
}
八、350:Intersection-of-Two-Arrays(II)
一、题目
给定两个数组,编写一个函数来计算它们的交集。
示例 1:
-
输入: nums1 = [1,2,2,1], nums2 = [2,2]
-
输出: [2,2]
示例 2:
-
输入: nums1 = [4,9,5], nums2 = [9,4,9,8,4]
-
输出: [4,9]
说明:
- 输出结果中每个元素出现的次数,应与元素在两个数组中出现的次数一致。
- 我们可以不考虑输出结果的顺序。
进阶:
- 如果给定的数组已经排好序呢?你将如何优化你的算法?
- 如果 nums1 的大小比 nums2 小很多,哪种方法更优?
- 如果 nums2 的元素存储在磁盘上,磁盘内存是有限的,并且你不能一次加载所有的元素到内存中,你该怎么办?
二、代码
package IMUHERO;
import java.util.TreeMap;
import java.util.ArrayList;
class Solution {
public int[] intersect(int[] nums1, int[] nums2) {
TreeMap<Integer,Integer>treeMap=new TreeMap<>();
for (int num:nums1){
if (!treeMap.containsKey(num)) {
treeMap.put(num,1);
}
else {
treeMap.put(num,treeMap.get(num)+1);
}
}
ArrayList<Integer>arrayList=new ArrayList<>();
for (int num:nums2){
if (treeMap.containsKey(num)){
arrayList.add(num);
treeMap.put(num,treeMap.get(num)-1);
if (treeMap.get(num)==0)treeMap.remove(num);
}
}
int [] reArr= new int[arrayList.size()];
for (int i=0;i<arrayList.size();i++){
reArr[i]=arrayList.get(i);
}
return reArr;
}
}