3. 无重复字符的最长子串
建立一个哈希表,遍历每个字符,将字符下标存进表里
left代表不重复子字符串的开始节点
right代表遍历索引
TypeScript
function lengthOfLongestSubstring(s: string): number {
const lastIndex = new Map<string,number>()
let left = 0
let max = 0
for(let right=0;right<s.length;right++){
const cur = s[right]
if(lastIndex.has(cur)){
left = Math.max(left,lastIndex.get(cur)+1)
}
lastIndex.set(cur,right)
max = Math.max(max,right-left+1)
}
return max
};
146.LRU缓存
map是能记录插入顺序的键值对
.size能获取哈希表的长度
.set(key,value),相同的key,新的值覆盖先前的value
.has(key)判断,key在不在哈希表里
.get(key)获取哈希表中key对应的value值
.keys()获取哈希表的所有键值
.keys().next().value获取哈希表中键的最先插进去的键值
TypeScript
class LRUCache {
//定义变量
private contain:Map<number,number>
private capacity:number
constructor(capacity: number) {
this.contain = new Map()
this.capacity = capacity
}
get(key: number): number {
//如果存在,删除原来的值,重新插入
if(this.contain.has(key)){
const value = this.contain.get(key)!
this.contain.delete(key)
this.contain.set(key,value)
return value
}else{
return -1
}
}
put(key: number, value: number): void {
if(this.contain.has(key)){
this.contain.delete(key)
}
this.contain.set(key,value)
if(this.contain.size>this.capacity){
//找到最先插入的键,删除
const trail = this.contain.keys().next().value
this.contain.delete(trail)
}
}
}
/**
* Your LRUCache object will be instantiated and called as such:
* var obj = new LRUCache(capacity)
* var param_1 = obj.get(key)
* obj.put(key,value)
*/
206.反转链表
1->2->3->4->5-null
结果:null<-1<-2<-3<-4<-5
pre cur
cur.next = pre cur.next指向null
pre和cur各进一步
TypeScript
/**
* Definition for singly-linked list.
* class ListNode {
* val: number
* next: ListNode | null
* constructor(val?: number, next?: ListNode | null) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
* }
*/
function reverseList(head: ListNode | null): ListNode | null {
if(!head || head.next===null) return head
let pre:ListNode | null = null
let cur:ListNode | null = head
while(cur){
let next = cur.next
cur.next = pre
pre = cur
cur = next
}
return pre
};
25.K个一组翻转链表
先翻转前k个元素,递归翻转剩余的链表
head表示旧链表的头
pre表示新链表的头
cur表示下一组翻转链表的开始节点
TypeScript
/**
* Definition for singly-linked list.
* class ListNode {
* val: number
* next: ListNode | null
* constructor(val?: number, next?: ListNode | null) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
* }
*/
function reverseKGroup(head: ListNode | null, k: number): ListNode | null {
if(!head || k<=1) return head
let count = 0
let index:ListNode | null = head
while(index && count<k){
index = index.next
count++
}
if(count<k) return head
let pre:ListNode | null = null
let cur:ListNode | null = head
for(let i=0;i<k;i++){
const next = cur.next
cur.next = pre
pre = cur
cur = next
}
head.next = reverseKGroup(cur,k)
return pre
};
15.三数之和
滑动窗口
1.从小到大排序,
2.如果numi>0,证明和>0,不符,直接结束循环。有相同的跳过进入下一次循环
2.i从0开始,最后的索引是倒数第三个;j=i+1;z从最后一个索引开始往前
3.计算当前的和,>0,窗口向左移z--;<0,窗口右移j++
4.相等,符合。判断下一个是不是相同的值,相同跳过,最后z--,j++
TypeScript
function threeSum(nums: number[]): number[][] {
nums.sort((a,b)=>a-b)
const res:number[][] = []
for(let i=0;i<=nums.length-2;i++){
if(nums[i]>0) break
if(i>0 && nums[i]===nums[i-1]) continue
let j = i+1
let k = nums.length-1
while(j<k){
const sum = nums[i]+nums[j]+nums[k]
if(sum>0){
k--
}else if(sum<0){
j++
}else{
res.push([nums[i],nums[j],nums[k]])
while(j<k && nums[j]===nums[j+1]) j++
while(j<k && nums[k]===nums[k-1]) k--
j++
k--
}
}
}
return res
};
共勉