问题描述
给定一个循环双向链表deck
(拥有字段head
),它具有节点card
(拥有字段next
和prev
),我想在牌组上执行“三重切割”,这被定义为在牌组中挑选两张牌,并将第一张牌之前的元素替换为第二张牌之后的元素。方法必须是 O(1)
。
我的想法是生成两个新的循环双向链表deck1和deck2,并将deck的左侧部分和deck右侧部分分别存储在其中。我制作了下图以更好地说明我要实现的目标:
以下是我的编码尝试,问题出现在尝试切片“这个”甲板,并以适当的顺序重新组合切片后的甲板和新的 2 个甲板时。
public void tripleCut(Card firstCard,Card secondCard) {
// inputs : firstCard = 3H
// inputs : secondCard = 2C
// this deck : AC 2D 3H 4D AD 4H 4C AH 2C RJ 3C BJ 3D 2H
// deck 3
Deck d3 = new Deck();
d3.head = secondCard.next;
secondCard = d3.head.prev;
d3.head.prev = this.head.prev;
// d3.head = RJ
// d3.head.prev = 2H
//deck 1
Deck d1 = new Deck();
d1.head = this.head;
d1.head.prev = firstCard.prev;
// d1.head = AC
// d1.head.prev = 2D
// Slicing the two decks from 'this' deck
this.head.prev = secondCard;
secondCard.next = this.head;
this.head = firstCard;
firstCard.prev = secondCard;
this.head.prev = secondCard;
secondCard.next= this.head;
head.prev.next=d1.head;
head.prev = d1.head.prev;
}
当我尝试重新组合套牌时,我得到了胡说八道,这表明我上面所做的不正确。你们会如何解决这个问题?即使是伪代码也会有用,我已经被困在这个问题上太久了,我真的很迷茫。
解决方法
澄清案例
- left = null 和/或 right = null
- 左==右==头
- 左边总是在右边
基本思路
剪切
假设头部可访问且保持左/右顺序
- 三个参数——头、左、右
- 派生tail = head.prev
- 备份 beforeLeft = left.prev 和 afterRight = right.next
- 切尾,头循环(tail.next = head.prev = null)
- cut left.prev = right.next = null,beforeLeft.next = null,afterRight.prev = null
加入
- 六个参数 - 头、尾、左、右、前左、后右
- 头部会在右后移动(right.next = head,head.prev = right)
- tail 会在左前移动(left.prev = tail,tail.next = left)
- 设置新的头尾(head = afterRight,tail = beforeLeft)
- 加入新的头部和尾部(head.prev = tail,tail.next = head)
我还没有测试过这个及其可能的方法之一。