1.链表内指定区间反转 - js
描述
将一个节点数为 size 链表 m 位置到 n 位置之间的区间反转,要求时间复杂度 O(n)O(n),空间复杂度 O(1)O(1)。
例如:
给出的链表为 1→2→3→4→5→NULL, m=2,n=4m=2,n=4,
返回 1→4→3→2→5→NULL.
示例1
输入:{1,2,3,4,5},2,4
返回值:{1,4,3,2,5}
思路:链表的题思路简单编码麻烦,老是在弥缝子
1.根据题目给定的区间将链表切割成三段,并且将区间内的一段反转之后再次链接即可
代码实现
function reverseBetween( head , m , n ) {
// write code here
if(!head || !head.next || m == n) return head
// 反转链表
function reserve(root){
let node = root
let prev = node
while(node){
prev = node
node = node.next
if(prev === root){
prev.next = null
}else{
prev.next = root
}
root = prev
}
return root
}
let count = 0
let frist = null
if(m > 1){
frist = head
}
let mid = null
let end = null
let node = head
let fristEnd = null
while(node){
count ++
if(count === m - 1){
fristEnd = node
node = node && node.next
count ++
fristEnd.next = null
}
if(count === m){
mid = node
}
if(count === n){
end = node && node.next
node.next = null
}
node = node && node.next
}
mid = reserve(mid)
// 链接链表
if(frist){
node = frist
while(node && node.next) node = node.next
node.next = mid
}
node = mid
while(node && node.next) node = node.next
node.next = end
return frist ? frist : mid
}
2.划分链表-js
描述
给出一个长度为 n 的单链表和一个值 x ,单链表的每一个值为 listi ,请返回一个链表的头结点,要求新链表中小于 x 的节点全部在大于等于 x 的节点左侧,并且两个部分之内的节点之间与原来的链表要保持相对顺序不变。
例如:
给出 1→4→3→2→5→2 和 x = 3
返回 1→2→2→4→3→5
示例1
输入:{1,4,3,2,5,2},3
返回值:{1,2,2,4,3,5}
思路:找到第一个比目标值大的节点maxNode之后,暂停当前指针,新创建一个指针向后遍历找到第一个比目标值小的节点minNode,
插入到当前指针所指的maxNode节点前面,需要注意的是插入后需要将遍历指针向前移动一位以保证遍历指针一直指向当前的这个最大节点maxNode,
因为后面所有的minNode节点需要全部插入到这个节点前面,才能保证大于等于目标值的节点顺序不变。
代码实现
function partition( head , x ) {
// write code here
let node = head
let minNode = null
let maxNode = null
let prevMaxNode = null
let prevMinNode = null
while(node){
if(node.val >= x){
maxNode = node
let newNode = node
while(newNode){
if(newNode.val < x){
minNode = newNode
break
}
prevMinNode = newNode
newNode = newNode && newNode.next
}
}
if(maxNode && minNode){
prevMinNode.next = minNode && minNode.next
minNode.next = node
// 这里需要注意一下 如果第一个节点的值就比目标值大的话是没有前置节点的所以要判断一下
if(prevMaxNode) {
prevMaxNode.next = minNode
// 并且在凭借完列表后遍历指针需要向前走一步,因为后面所有比目标值小的节点将全部插在这个节点后面
node = prevMaxNode
}else {
head = minNode
node = head
}
maxNode = null
minNode = null
}
prevMaxNode = node
node = node && node.next
}
return head
}