剑指offer-之-哈希表
Posted 小玄ks
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了剑指offer-之-哈希表相关的知识,希望对你有一定的参考价值。
本题核心:哈希表,用哈希表来存原链表的每个节点和新链表的每个节点,两者是一一对应的关系。我们先存储只带有val的每一个新节点,那么哈希表中存储的每一个旧节点和每一个新节点都是key-value的关系,接下来就是通过这种关系让新节点的next和random指向正确的节点,最后返回新节点的头结点即可。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode deleteNode(ListNode head, int val) {
if(head == null) return null;
ListNode newHead = new ListNode(-1);
newHead.next = head;
ListNode cur = head;
ListNode pre = newHead;
while(cur != null){
if(cur.val == val){
pre.next = cur.next;
}
pre = cur;
cur = cur.next;
}
return newHead.next;
}
}
本题用哈希表可以很简便地解决,关键点在于key-value键值对类型是Character-Boolean。Character:对应每一个字符,Boolean:对应该字符是否只出现一次,若只出现一次为true,否则为flase。将每个字符存储到哈希表中后,再从原先字符串的顺序遍历,判断每个字符对应的value值,得到第一个只出现一次的字符。
class Solution {
public char firstUniqChar(String s) {
Map<Character,Boolean> map = new HashMap<>();
char[] ch = s.toCharArray();
for(char c : ch){
map.put(c,!map.containsKey(c));
}
for(char c : ch){
if(map.get(c)) return c;
}
return ' ';
}
}
本题的主要思想是动态规划,但是需要用到哈希表来存储数据。tmp是以当前字符为尾字符的最长不含重复字符字符串的最大长度,res为当前遍历到的最长不包含重复字符的字符串的最大长度。
哈希表中存储的key:字符串中的字符,value:该字符在字符串中的下标。
因为字符有可能是重复的,所以当遍历到重复字符时,会刷新哈希表中该字符的value值,而 i 为字符在这次刷新前该字符的下标,那么当前的i和j对应的就是该字符串中相同的两个字符下标,j - i就是 以 j 对应的字符
为尾字符的字符串长度。
但是j-i这个字符串里面可能有其他重复字符,所以我们将tmp与j-i来比较,刷新tmp的值,让tmp存储的是不含重复字符的子字符串长度
。
如果tmp >= j - i
,说明j-i对应字符串在tmp对应字符串中,那么将tmp刷新为j-i。
如果tmp < j - i
,说明 j - i 对应的字符串中包含tmp对应的字符串,那么j-i中必然有重复字符,所以将不能将tmp刷新为j-i,只需要将tmp+1即可。
class Solution {
public int lengthOfLongestSubstring(String s) {
Map<Character,Integer> map = new HashMap<>();
int tmp = 0;
int res = 0;
for(int j = 0; j < s.length(); ++j){
int i = map.getOrDefault(s.charAt(j),-1);
map.put(s.charAt(j),j);
tmp = (tmp < j-i) ? tmp+1 : j-i;
res = Math.max(res,tmp);
}
return res;
}
}
以上是关于剑指offer-之-哈希表的主要内容,如果未能解决你的问题,请参考以下文章
Leetcocde剑指 Offer 03. 数组中重复的数字(哈希表+原地置换法)