本文仅供自己复习用
1、剑指 Offer 22. 链表中倒数第k个节点
a、快慢指针
/**
* @param {ListNode} head
* @param {number} k
* @return {ListNode}
*/
var getKthFromEnd = function(head, k) {
let quick = head, slow = head
for(let i = 0; i < k; i++) {
quick = quick.next
}
while(quick !== null) {
quick = quick.next
slow = slow.next
}
return slow
};
2、剑指 Offer 24. 反转链表
/**
* @param {ListNode} head
* @return {ListNode}
*/
var reverseList = function(head) {
let after = null
let node = head
let next = null
while(node !== null) {
let temp = node.next
node.next = after
after = node
node = temp
}
return after
};
3、剑指 Offer 25. 合并两个排序的链表
/**
* @param {ListNode} l1
* @param {ListNode} l2
* @return {ListNode}
*/
var mergeTwoLists = function(l1, l2) {
let node = new ListNode('')
let head = node
let pre = null
let buildNode = function(val) {
node.val = val
pre = node
node.next = new ListNode('')
return node.next
}
while(l1 !== null && l2 !== null) {
if(l1.val < l2.val) {
node = buildNode(l1.val)
l1 = l1.next
} else {
node = buildNode(l2.val)
l2 = l2.next
}
}
while(l1 !== null) {
node = buildNode(l1.val)
l1 = l1.next
}
while(l2 !== null) {
node = buildNode(l2.val)
l2 = l2.next
}
if(head.val === '') {
return null
}
pre.next = null
return head
};
4、剑指 Offer 26. 树的子结构
5、剑指 Offer 27. 二叉树的镜像
a、递归
这里最关键的就是用中间量存一下
/**
* @param {TreeNode} root
* @return {TreeNode}
*/
var mirrorTree = function(root) {
let reverse = function(node) {
if(node === null) {
return null
}
// 必须用中间量存一下,这里很关键
let temp = node.right
node.right = reverse(node.left)
node.left = reverse(temp)
return node
}
return reverse(root)
};
6、剑指 Offer 28. 对称的二叉树
a、递归
/**
* @param {TreeNode} root
* @return {boolean}
*/
var isSymmetric = function(root) {
if(root === null) {
return true
}
let judge = function(left, right) {
if(left === null && right === null) {
return true
} else if(left === null || right === null) {
return false
}
let out = judge(left.left, right.right)
let inner = judge(left.right, right.left)
return left.val === right.val && out && inner
}
return judge(root.left, root.right)
};
7、剑指 Offer 29. 顺时针打印矩阵
a、暴力破
这里有两个重点,因为我用的是shift或pop,所以可能出现[[], [], []]这种情况,所以横着拿数据时得判断
/**
* @param {number[][]} matrix
* @return {number[]}
*/
var spiralOrder = function(matrix) {
let res = []
while(matrix.length !== 0) {
res.push(...matrix.shift())
for(let i = 0; i < matrix.length; i++) {
// 这里很重要
if(matrix[i].length === 0) break
res.push(matrix[i].pop())
}
if(matrix.length > 0) {
res.push(...(matrix.pop().reverse()))
}
for(let i = matrix.length - 1; i > 0; i--) {
// 这里很重要
if(matrix[i].length === 0) break
res.push(matrix[i].shift())
}
}
return res
};
8、剑指 Offer 30. 包含min函数的栈
a、辅助栈
使用一个单调递减的辅助栈(必须把第一个元素存进去,这样是为了跟另外的那一个栈保持一致,这样另外那个栈不为空,这个就不会为空)
/**
* initialize your data structure here.
*/
var MinStack = function() {
this.stack = []
this.minStack = []
};
/**
* @param {number} x
* @return {void}
*/
MinStack.prototype.push = function(x) {
// 这里如果跟最小值相等也要放进去
if(this.stack.length === 0 || x <= this.minStack[this.minStack.length - 1]) {
this.minStack.push(x)
}
this.stack.push(x)
};
/**
* @return {void}
*/
MinStack.prototype.pop = function() {
if(this.stack.pop() === this.minStack[this.minStack.length - 1]) {
this.minStack.pop()
}
};
/**
* @return {number}
*/
MinStack.prototype.top = function() {
return this.stack[this.stack.length - 1]
};
/**
* @return {number}
*/
MinStack.prototype.min = function() {
return this.minStack[this.minStack.length - 1]
};
/**
* Your MinStack object will be instantiated and called as such:
* var obj = new MinStack()
* obj.push(x)
* obj.pop()
* var param_3 = obj.top()
* var param_4 = obj.min()
*/
9、剑指 Offer 31. 栈的压入、弹出序列
10、剑指 Offer 32 - I. 从上到下打印二叉树
/**
* @param {TreeNode} root
* @return {number[]}
*/
var levelOrder = function(root) {
if(root === null) {
return []
}
let queue = [root]
let res = []
while(queue.length !== 0) {
let val = queue.shift()
res.push(val.val)
if(val.left !== null) {
queue.push(val.left)
}
if(val.right !== null) {
queue.push(val.right)
}
}
return res
};