[M Simulation] lc1721. Exchange the nodes in the linked list (simulation + weekly contest 223_2)

1. Source of the subject

Link: 1721. Exchange nodes in the linked list

2. Topic analysis

I have encountered the linked list questions in the exam, don't smash, how to speculate and how to come. Generally, the linked list is reconstructed after the value is stored in the array for operation, or the pointer operation is not performed, and only the value exchange is performed. The last is to operate the pointer of the linked list in a practical sense, to change the pointer point, and to do this to add to the question, which directly troubles autism...

note:

  • This head node may change, you need to use a virtual head node
  • Linked list pointer writing is very troublesome. Especially when kand n-knode adjacent to fast when he has had a lot of problems need special pointer sentence. Just look at the code comments.

  • Time complexity : O (n) O(n)O ( n )
  • Space complexity : O (1) O (1)O ( 1 )

Code:

// 数组+链表重建
class Solution {
    
    
public:
    ListNode* swapNodes(ListNode* head, int k) {
    
    
        vector<int> a;
        for (auto p = head; p; p = p->next) a.push_back(p->val);
        swap(a[k - 1], a[a.size() - k]);
        head = new ListNode(a[0]);
        auto tail = head;
        for (int i = 1; i < a.size(); i ++ ) 
            tail = tail->next = new ListNode(a[i]);
        return head;
    }
};

// swap()交换值
class Solution {
    
    
public:
    ListNode* swapNodes(ListNode* head, int k) {
    
    
        auto dummy = new ListNode(-1);
        dummy->next = head;
        int n = 0;
        for (auto p = dummy; p; p = p->next) n ++ ;
        auto a = dummy, b = dummy;
        for (int i = 0; i < k; i ++ ) a = a->next;
        for (int i = 0; i < n - k; i ++ ) b = b->next;
        swap(a->val, b->val);
        return dummy->next;
    }
};

// swap()交换 简易版
class Solution {
    
    
public:
    ListNode* swapNodes(ListNode* head, int k) {
    
    
        int n = 0;
        for (auto p = head; p; p = p->next) n ++ ;
        auto a = head, b = head;
        for (int i = 0; i < k - 1; i ++ ) a = a->next;
        for (int i = 0; i < n - k; i ++ ) b = b->next;
        swap(a->val, b->val);
        return head;
    }
};

// 标准链表做法,十分麻烦,边界情况十分多
class Solution {
    
    
public:
    ListNode* swapNodes(ListNode* head, int k) {
    
    
        auto dummy = new ListNode(-1);
        dummy->next = head;
        int n = 0;
        for (auto p = dummy; p; p = p->next) n ++ ;
        k ++ ;
        auto a = dummy;		// a 是第k节点的前一个
        for (int i = 0; i < k - 2; i ++ ) a = a->next;
        auto b = dummy;		// b 是倒数第k节点的前一个
        for (int i = 0; i < n - k; i ++ ) b = b->next;

        if (a == b) return dummy->next;

        auto pa = a->next, qa = pa->next;	// 该记的全部记录下来,便于指针改变
        auto pb = b->next, qb = pb->next;
        if (a->next == b) {
    
    					// 如果出现距离太近,可能交换完产生环的情况
            a->next = qa, qa->next = pa;
            pa->next = qb;
            return dummy->next;
        } else if (b->next == a) {
    
    			// 同上,这是两个特殊的边界情况
            b->next = qb, qb->next = pb;
            pb->next = qa;
            return dummy->next;
        }

        pa->next = qb, b->next = pa;		// 正常情况下,改变指针指向即可
        pb->next = qa, a->next = pb;

        return dummy->next;
    }
};

Guess you like

Origin blog.csdn.net/yl_puyu/article/details/112718344