返回
算法精进系列之链表回文检测
前端
2024-01-17 18:36:45
回文链表
回文链表是一种特殊的链表,它从左读和从右读都是一样的。例如,以下链表是一个回文链表:
1 -> 2 -> 3 -> 2 -> 1
这个链表从左读是1 -> 2 -> 3 -> 2 -> 1,从右读也是1 -> 2 -> 3 -> 2 -> 1。
判断回文链表的算法
判断回文链表的算法主要有以下几个步骤:
- 将链表分为两部分,前半部分和后半部分。
- 反转后半部分的链表。
- 比较前半部分和后半部分的链表,如果相等,则链表是回文链表,否则不是。
JavaScript代码示例
// 定义链表节点对象
function Node(data) {
this.data = data;
this.next = null;
}
// 定义链表类
function LinkedList() {
this.head = null;
this.tail = null;
// 在链表尾部添加一个新节点
this.add = function(data) {
let newNode = new Node(data);
if (this.head === null) {
this.head = newNode;
this.tail = newNode;
} else {
this.tail.next = newNode;
this.tail = newNode;
}
};
// 反转链表
this.reverse = function() {
let prev = null;
let current = this.head;
let next = null;
while (current !== null) {
next = current.next;
current.next = prev;
prev = current;
current = next;
}
this.head = prev;
};
// 判断链表是否为回文链表
this.isPalindrome = function() {
// 将链表分为两部分
let slow = this.head;
let fast = this.head;
while (fast !== null && fast.next !== null) {
slow = slow.next;
fast = fast.next.next;
}
// 反转后半部分的链表
let後半部 = slow;
後半部.reverse();
// 比较前半部分和后半部分的链表
let前半部 = this.head;
while (後半部 !== null) {
if (前半部.data !== 後半部.data) {
return false;
}
前半部 = 前半部.next;
後半部 = 後半部.next;
}
return true;
};
}
// 创建一个回文链表
let linkedList = new LinkedList();
linkedList.add(1);
linkedList.add(2);
linkedList.add(3);
linkedList.add(2);
linkedList.add(1);
// 判断链表是否为回文链表
if (linkedList.isPalindrome()) {
console.log("链表是回文链表");
} else {
console.log("链表不是回文链表");
}
运行上面的代码,将在控制台输出"链表是回文链表",因为创建的链表是一个回文链表。如果将链表修改为1 -> 2 -> 3 -> 4 -> 5,然后运行代码,将在控制台输出"链表不是回文链表",因为修改后的链表不是回文链表。
总结
回文链表是一种特殊的链表,它从左读和从右读都是一样的。判断回文链表的算法主要有以下几个步骤:
- 将链表分为两部分,前半部分和后半部分。
- 反转后半部分的链表。
- 比较前半部分和后半部分的链表,如果相等,则链表是回文链表,否则不是。
本文提供了详细的JavaScript代码示例,帮助读者理解并掌握算法的实现原理。