描述
給一個(gè)來(lái)自已經(jīng)排過(guò)序的循環(huán)鏈表的節(jié)點(diǎn),寫(xiě)一個(gè)函數(shù)來(lái)將一個(gè)值插入到循環(huán)鏈表中,并且保持還是有序循環(huán)鏈表。給出的節(jié)點(diǎn)可以是鏈表中的任意一個(gè)單節(jié)點(diǎn)。返回插入后的新鏈表。
注意事項(xiàng)
3->5->1 是一個(gè)循環(huán)鏈表,所以 3 是 1 的下一個(gè)節(jié)點(diǎn)。3->5->1 與 5->1->3 相同
樣例
給一個(gè)鏈表:3->5->1
插入值 4
返回 5->1->3->4
思路
循環(huán)鏈表的插入要考慮四種情況:
- 鏈表為空
- 鏈表只有一個(gè)結(jié)點(diǎn)
- 鏈表值不全部相等時(shí)的兩種插入:
a. 順序排列的合適位置
b. 最大值最小值的中間插入- 鏈表值全部相等時(shí),在表頭或表尾的任意插入
代碼
- version1
/**
* Definition for ListNode
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
/**
* @param node a list node in the list
* @param x an integer
* @return the inserted new list node
*/
public ListNode insert(ListNode node, int x) {
// 鏈表為空時(shí),新建一個(gè)結(jié)點(diǎn),node.value = x,結(jié)點(diǎn)的next指針指向自己
if (node == null) {
node = new ListNode(x);
node.next = node;
return node;
}
// 在鏈表內(nèi)部尋找合適的插入位置
// current是當(dāng)前結(jié)點(diǎn),node是鏈表頭結(jié)點(diǎn)
ListNode current = node;
ListNode prev = null;
do {
/* prev和current都向后移一位
* 不能寫(xiě)成prev.next = current;
* 如果是普通鏈表可能問(wèn)題不大,但循環(huán)鏈表的話(huà)會(huì)出問(wèn)題,
* 因?yàn)檠h(huán)鏈表實(shí)際上就是一個(gè)環(huán)形鏈表,
* 沒(méi)有頭尾,這種情況下給某一個(gè)結(jié)點(diǎn)在外面加了一個(gè)新的連接結(jié)點(diǎn),
* 在遍歷循環(huán)鏈表時(shí)一定會(huì)出現(xiàn)超時(shí)
*/
prev = current;
current = current.next;
// 兩種滿(mǎn)足條件的插入情況,用break結(jié)束循環(huán)
if (x <= current.val && x >= prev.val) {
break;
}
if ((prev.val > current.val) && (x < current.val || x > prev.val)) {
break;
}
// 剛開(kāi)始current = node,不斷后移,若current再次等于node則證明遍歷整個(gè)鏈表一圈
} while (current != node);
// 鏈表內(nèi)部位置都不滿(mǎn)足條件,可以說(shuō)明鏈表都是值一樣的結(jié)點(diǎn),直接在邊緣插入
// 創(chuàng)建新結(jié)點(diǎn),把新結(jié)點(diǎn)插入到合適的位置
ListNode newNode = new ListNode(x);
newNode.next = current;
prev.next = newNode;
return newNode;
}
}
- version2 不用do while 邏輯更清晰些
/**
* Definition for ListNode
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
/*
* @param node: a list node in the list
* @param x: An integer
* @return: the inserted new list node
*/
public ListNode insert(ListNode node, int x) {
// 鏈表為空
if (node == null) {
node = new ListNode(x);
node.next = node;
return node;
}
ListNode current = node;
ListNode prev = null;
// 鏈表只有一個(gè)結(jié)點(diǎn)
prev = current;
current = current.next;
if (current == node) {
ListNode newNode = new ListNode(x);
current.next = newNode;
newNode.next = current;
}
// 鏈表結(jié)點(diǎn)值不全部相等
// 當(dāng)鏈表值相等時(shí),下面的 if 根本不會(huì)執(zhí)行
while (current != node) {
if ((prev.val <= x && x <= current.val) ||
(prev.val > current.val && (prev.val < x || x < current.val))) {
ListNode newNode = new ListNode(x);
prev.next = newNode;
newNode.next = current;
break;
}
prev = current;
current = current.next;
}
// 鏈表結(jié)點(diǎn)值全部相等
ListNode newNode = new ListNode(x);
prev.next = newNode;
newNode.next = current;
return node;
}
}