船长表情包镇楼
链表
- 结点
- 链状结构
- 特点
- 链表中的每个结点至少包含两个部分:数据域和指针域
- 链表中的每个结点,通过指针域的值,形成一个线性结构
- 查找结点O(n),插入结点O(1),删除结点O(1)
- 不适合快速的定位数据,适合动态插入以及删除的应用场景
- 应用场景
- 操作系统内的动态内存分配
- LRU(Least Recently Used)缓存淘汰算法(近期最少使用)
船长金句:学数据结构,学算法,学的是思维方式,不是学的具体程序的实现,具体程序的实现是根据编程的经验来的,同一种思想,可以用不同的方式表达出来
LeetCode肝题(以训练为目的)
-
- 环形链表
var hasCycle = function(head) {
if (!head) return false
let p = head, q = head
while(q && q.next) {
p = p.next
q = q.next.next
if (p == q) return true
}
return false
};
-
- 环形链表 II
var detectCycle = function(head) {
if(!head) return null
let p = head, q = head.next
while(q && q.next) {
p = p.next
q = q.next
if (p == q) {
q = head
while(p != q) {
p = p.next
q = q.next
}
return p
}
q = q.next
}
return null
};
-
- 快乐数
var nextNum = function(num) {
let sum = 0
while(num > 0) {
sum += (num % 10) * (num % 10)
num = parseInt(num / 10)
}
return sum
}
var isHappy = function(n) {
if (n == 1) return true
let p = nextNum(n), q = nextNum(nextNum(n))
while(q != 1 && nextNum(q) != 1) {
p = nextNum(p)
q = nextNum(q)
if (p == q) return false
q = nextNum(q)
}
return true
};
-
- 反转链表
var reverseList = function(head) {
if (!head) return head
let pre = null, cut = head, p = head.next
while(cut) {
cut.next = pre
pre = cut
cut = p
if (p) p = p.next
}
return pre
};
var reverseList = function(head) {
if (!head || !head.next) return head
let tail = head.next, p = reverseList(head.next)
head.next = tail.next
tail.next = head
return p
};
-
- 反转链表 II
var reverseN = function(head, n) {
if (n == 1) return head
let tail = head.next, p = reverseN(head.next, n - 1)
head.next = tail.next
tail.next = head
return p
}
var reverseBetween = function(head, left, right) {
let ret = new ListNode(null, head), p = ret, num = right - left + 1
while(--left) {
p = p.next
}
p.next = reverseN(p.next, num)
return ret.next
};
-
- K 个一组翻转链表
var __reverseN = function(head, n) {
if (n == 1) return head
let tail = head.next, p = __reverseN(head.next, n - 1)
head.next = tail.next
tail.next = head
return p
}
var reverseN = function(head, n) {
let cut = n, p = head
while(--n && p) p = p.next
if (!p) return head
return __reverseN(head, cut)
}
var reverseKGroup = function(head, k) {
let ret = new ListNode(null, head), p = ret, q = p.next
while((p.next = reverseN(q, k)) != q) {
p = q
q = q.next
}
return ret.next
};
-
- 旋转链表
var rotateRight = function(head, k) {
if (!head) return head
let p = head, cut = 1
while(p.next) {
p = p.next
cut++
}
console.log(cut)
p.next = head
k = cut - k % cut
while(k--) {
head = head.next
p = p.next
}
p.next = null
return head
};
-
- 两两交换链表中的结点
var swapPairs = function(head) {
let ret = new ListNode(null, head), p = ret, q = p.next
while((p.next = reverseN(q, 2)) != q) {
p = q
q = q.next
}
return ret.next
};
-
- 删除链表的倒数第 N 个结点
var removeNthFromEnd = function(head, n) {
if (!head) return head
let ret = new ListNode(null, head), p = ret, q = p.next
while(n--) {
q = q.next
}
if (!q) return head.next
while(q) {
p = p.next
q = q.next
}
p.next = p.next.next
return ret.next
};
-
- 删除排序链表中的重复元素
var deleteDuplicates = function(head) {
let p = head
while(p && p.next) {
if (p.val == p.next.val) {
p.next = p.next.next
} else {
p = p.next
}
}
return head
};
-
- 删除排序链表中的重复元素 II
var deleteDuplicates = function(head) {
let ret = new ListNode(null, head), p = ret, q
while(p.next) {
if (p.next.next && p.next.val == p.next.next.val) {
q = p.next.next
while(q && q.val == p.next.val) {
q = q.next
}
p.next = q
} else {
p = p.next
}
}
return ret.next
};
-
- 分隔链表
var partition = function(head, x) {
let ret1 = new ListNode(0, null), ret2 = new ListNode(0, null), p1 = ret1, p2 = ret2, q = head
while(q) {
if (q.val < x) {
p1.next = q
p1 = p1.next
q = q.next
} else {
p2.next = q
p2 = p2.next
q = q.next
}
}
p2.next = null
p1.next = ret2.next
return ret1.next
};
-
- 复制带随机指针的链表
var copyRandomList = function(head) {
if (!head) return head
let p = head, new_head, q;
while(p) {
q = new Node(p.val)
q.next = p.next
q.random = p.random
p.next = q
p = q.next
}
p = head.next
while(p) {
if (p.random) p.random = p.random.next
p = p.next
if (p) p = p.next
}
p = head
new_head = head.next
while(p) {
q = p.next
p.next = q.next
if (p.next) q.next = p.next.next
p = p.next
}
return new_head
};