题目地址:
https://www.lintcode.com/problem/swap-two-nodes-in-linked-list/description
给定一个链表,再给定两个数 v 1 v_1 v1和 v 2 v_2 v2,要求将链表中等于这两个数的节点互换。要求不允许只换值,而要换两个节点。如果找不到则什么也不操作。
要分成两种情况考虑:
1、两个节点相邻,此时只需要改变三条边就可以了;
2、不相邻,此时需要改四条边。
代码如下:
public class Solution {
/**
* @param head: a ListNode
* @param v1: An integer
* @param v2: An integer
* @return: a new head of singly-linked list
*/
public ListNode swapNodes(ListNode head, int v1, int v2) {
// write your code here
ListNode dummy = new ListNode(0);
dummy.next = head;
ListNode l1, l2;
l1 = l2 = dummy;
// 先找到两个节点
while (l1.next != null && l1.next.val != v1) {
l1 = l1.next;
}
while (l2.next != null && l2.next.val != v2) {
l2 = l2.next;
}
// 如果有一个没找到,则什么也不做,直接返回原链表表头
if (l1.next == null || l2.next == null) {
return head;
}
if (l1.next != l2 && l2.next != l1) {
// 处理不相邻的情况
ListNode n1 = l1.next.next, n2 = l2.next.next;
// l1 -> v1 -> n1 -> ... -> l2 -> v2 -> n2
l1.next.next = n2;
l2.next.next = n1;
ListNode vv2 = l2.next;
l2.next = l1.next;
l1.next = vv2;
} else {
// 处理相邻的情况。为了方便,把l1放到l2前面
if (l1.next != l2) {
ListNode tmp = l1;
l1 = l2;
l2 = tmp;
}
// l1 -> v1 == l2 -> v2 -> n2
ListNode vv2 = l2.next;
l1.next.next = vv2.next;
vv2.next = l1.next;
l1.next = vv2;
}
return dummy.next;
}
}
class ListNode {
int val;
ListNode next;
ListNode(int x) {
val = x;
}
}
时间复杂度 O ( n ) O(n) O(n),空间 O ( 1 ) O(1) O(1)。