查找问题 set 与 map
主要问题
1.查找有无 set
set (实现collection接口)
实现类:
hashset(hashcode()和equals()保证唯一性)
treeset(对象排序)(红黑树)
linkedhashset(双向链表和哈希表)
底层实现:hashmap 对应value是一个静态object对象。
2.对应频次 map
map(独立接口)
实现类:
hashmap(数组+链表/红黑树)(无synchronized 线程不安全、效率较高)(允许null)
解决hash冲突:
- 再散列
- 链表
hashtable
synchronized修饰,效率低;no null(equals())需要对象。
linkedhashmap\
arraymap(android.util中的类)
对hash数组二分查找。
相比hashmap,内存消耗减少30%。
(hashmap初始容量16,达到0.75时扩大一倍,每次扩容要重新计算成员位置;arraymap,size大于8,申请size*1.5,4-8申请8,小于4申请4,但是扩容频次高。所以数据量较大时hashmap更合适。)
treemap(红黑树)
父类:sortmap
相关算法题
202happy number
class Solution { public boolean isHappy(int n) { HashSet<Integer> h=new HashSet(); while(n!=1&&!h.contains(n)){//若某数字已经出现,则陷入循环,不符合。 h.add(n); n=sol(n); } return n==1; } public int sol(int n){ int sum=0; while(n>0){ int a=n%10; n=n/10; sum+=a*a; } return sum; } }
205. Isomorphic Strings
242. Valid Anagram
451. Sort Characters By Frequency
查找表经典问题
1.数据集大小?
2.n^2是否可接受?
class Solution { public int[] twoSum(int[] nums, int target) { Map <Integer,Integer> map=new HashMap<>(); int[] a=new int[2]; for(int i=0;i<nums.length;i++){ int b=target-nums[i]; if(map.containsKey(b)){ a[0]=map.get(b); a[1]=i; } map.put(nums[i],i); } return a; } }
15. 3Sum (也可以排序加双指针 O(n^2))
class Solution { public static List<List<Integer>> threeSum(int[] nums) { List<List<Integer>> ans = new ArrayList(); int len = nums.length; if(nums == null || len < 3) return ans; Arrays.sort(nums); if(len==3&&nums[0]==0&&nums[1]+nums[2]==0){ ans.add(Arrays.asList(0,0,0)); return ans; } for(int j=0;j<len;j++){ if(nums[j]>0)break; if(j>0&&nums[j]==nums[j-1])continue; Map<Integer,Integer> m=new HashMap(); for(int k=j+1;k<len;k++){ if(m.containsKey(-nums[j]-nums[k])){//两数之和变形 ans.add(Arrays.asList(nums[j],nums[k],-nums[j]-nums[k])); while(k+1<len&&nums[k+1]==nums[k])k++; } m.put(nums[k],k); } } return ans; } }
class Solution { public int threeSumClosest(int[] nums, int target) { int len=nums.length; if(len<3)return 0; Arrays.sort(nums); int res=nums[0]+nums[1]+nums[2]; int sum=0; for(int i=0;i<len;i++){ int l=i+1; int r=len-1; while(l<r){ sum=nums[i]+nums[l]+nums[r]; if(Math.abs(sum-target)<Math.abs(res-target)){ res=sum; } if(sum>target){ r--; }else if(sum<target){ l++; }else{ return res; } } } return res; } }