1、将有序数组转换为二叉搜索树
// 输入:nums = [-10,-3,0,5,9] // 输出:[0,-3,9,-10,null,5] || [0,-10,5,null,-3,null,9]
// 二叉树节点的定义。
function TreeNode(val, left, right) {
this.val = (val===undefined ? 0 : val)
this.left = (left===undefined ? null : left)
this.right = (right===undefined ? null : right)
}
/**
* @param {number[]} nums
* @return {TreeNode}
*/
var sortedArrayToBST = function(nums) {
return buildBST(nums, 0, nums.length - 1); // 递归入口
};
/**
* @param {number[]} nums
* @param {number} start 起点
* @param {number} end 终点
* @returns
*/
const buildBST = (nums, start, end) => {
if (start > end) { // 构成不了区间,返回null
return null
}
const midIndex = (start + end) >>> 1; // 求中间索引
console.log(midIndex);
const root = new TreeNode(nums[midIndex]); // 构建当前节点
root.left = buildBST(nums, start, midIndex - 1); // 构建左子树
root.right = buildBST(nums, midIndex + 1, end); // 构建左子树
return root
}
console.log(sortedArrayToBST(nums));
console.log(sortedArrayToBST(nums));
2、给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。
1 循环
var reverseList = function(head) {
if (!head) return null;
let pre = null, cur = head;
while (cur) {
// 关键: 保存下一个节点的值
let next = cur.next;
cur.next = pre;
pre = cur;
cur = next;
}
return pre;
};
2 递归
let reverseList = (head) =>{
let reverse = (pre, cur) => {
if(!cur) return pre;
// 保存 next 节点
let next = cur.next;
cur.next = pre;
return reverse(cur, next);
}
return reverse(null, head);
}
模拟运行数据
function ListNode(val, next) {
this.val = (val===undefined ? 0 : val)
this.next = (next===undefined ? null : next)
}
// 模拟运行数据
const nums = [1,2,3,4,5]
const listNode = []
const buildNode = (nums, len) => {
let leng = len > nums.length - 1 ? null : len
if (leng === null) return null
const root = new ListNode(nums[leng]); // 构建当前节点
if (nums.length > len) {
root.next = buildNode(nums, ++leng)
}
return root
}
console.log(buildNode(nums, 0));
//ListNode {
// val: 1,
// next: ListNode { val: 2, next: ListNode { val: 3, next: [ListNode] } }
//}
console.log(reverseList(buildNode(nums, 0)))
//ListNode {
// val: 5,
// next: ListNode { val: 4, next: ListNode { val: 3, next: [ListNode] } }
//}
3 模拟数组插入操作
/**
* 模拟数组插入操作
* @param {*} arr
* @param {*} index
* @param {*} data
*/
function insert(arr, index, data) {
for (let i = arr.length; i > index; i--) {
arr[i] = arr[i - 1];
}
arr[index] = data
}
const arr = [1,2,3,4,5,6]
insert(arr, 2, 11)
4 生成链表
/**
* 初始化节点
* @description 1、指针指向空 2、存储数据
*/
class ListNode {
constructor(key) {
this.prev = null;
this.next = null;
this.key = key;
}
}
/**
* 初始化单向链表
*/
class List {
constructor() {
this.head = null;
this.length = 0
}
static createNode(key) {
return new ListNode(key);
}
// 插入节点(插入到头节点之后)
insert(node) {
node.prev = null
node.next = this.head
// 如果head有指向的节点
if (this.head) {
node.prev = this.head
} else {
node.next = null
}
this.head = node
this.length++
}
// 搜索节点
find(key) {
let node = this.head
while(node !== null && node.key !== key) {
node = node.next
}
return node
}
// 删除节点
delete(node) {
if (this.length === 0) {
throw 'node is undefined'
}
/**
* 第一种情况
* 所要删除的节点刚好是第一个,也就是head指向的节点
* 将head指向所要删除节点的下一个节点(node.next)
*/
if (node === this.head) {
this.head = node.next
this.length--
return
}
// 查找所要删除节点的上一个节点
let prevNode = this.head
while (prevNode.next !== node) {
prevNode = prevNode.next
}
/**
* 要删除的节点为最后一个节点
* 寻找到所要删除节点的上一个节点(prevNode)
* 将prevNode中的指针指向NULL
*/
if (node.next === null) {
prevNode.next = null
}
/**
* 在列表中间删除某个节点
* 寻找到所要删除节点的上一个节点(prevNode)
* 将prevNode中的指针指向当前要删除的这个节点的下一个节点
*/
if (node.next) {
prevNode.next = node.next
}
this.length--
}
}
let a = List.createNode('a')
let b = List.createNode('b')
let c = List.createNode('c')
const list = new List()
list.insert(a)
list.insert(b)
list.insert(c)
console.log(list);
{
head: ListNode { next: ListNode { next: [ListNode], key: 'b' }, key: 'c' },
length: 3
}