左神算法书籍《程序员代码面试指南》——2_01在单链表和双链表中删除倒数第k个字节


【题目】
分别实现两个函数,一个可以删除单链表中倒数第K个节点,另一个可以删除双链表中倒数第K个节点。
【要求】
如果链表长度为N,时间复杂度达到O(N),额外空间复杂度达到O(1)。
【题解】
从头遍历链表,每移动一次,K--,直至移动到链表尾部,此时
k>0,说明k太大,链表不用删除
k==0,链表长度即是k, 删除头结点即可
k<0,再次重头遍历链表,每移动一次,k++,
当k==0时,此时结点为要删除结点的前结点,使其指向下一个结点即可
双向链表一样,只不过需要注意前结点就好

  1 #include <iostream>
  2 using namespace std;
  3 
  4 struct SNode
  5 {
  6     int val;
  7     SNode* next;
  8     SNode(int a = 0) :val(a), next(nullptr) {}
  9 };
 10 
 11 struct DNode
 12 {
 13     int val;
 14     DNode* pre;
 15     DNode* next;
 16     DNode(int a = 0) :val(a), pre(nullptr), next(nullptr) {}
 17 };
 18 
 19 template<typename T>
 20 void printList(T head)
 21 {
 22     T p = head->next;
 23     while (p)
 24     {
 25         cout << p->val << "->";
 26         p = p->next;
 27     }
 28     cout << endl;
 29 }
 30 
 31 SNode* DeleteSList(SNode* head, int k)
 32 {
 33     SNode*p = head->next;
 34     while (p)
 35     {
 36         --k;
 37         p = p->next;
 38     }
 39     if (k > 0)//k大于链表的长度,不用删除
 40         return head;
 41     else if (k == 0)//k==链表的长度,删除头结点即可
 42         return head->next;
 43     p = head;
 44     while (k != 0)//找到删除结点的前结点
 45     {
 46         ++k;
 47         p = p->next;
 48     }
 49     p->next = p->next->next;
 50     return head;
 51 }
 52 
 53 DNode* DeleteDList(DNode* head, int k)
 54 {
 55     DNode*p = head->next;
 56     while (p)
 57     {
 58         --k;
 59         p = p->next;
 60     }
 61     if (k > 0)//k大于链表的长度,不用删除
 62         return head;
 63     else if (k == 0)//k==链表的长度,删除头结点即可
 64         return head->next;
 65     p = head;
 66     while (k != 0)//找到删除结点的前结点
 67     {
 68         ++k;
 69         p = p->next;
 70     }
 71     p->next->next->pre = p;
 72     p->next = p->next->next;
 73     return head;
 74 }
 75 
 76 
 77 int main()
 78 {
 79     SNode* head1 = new SNode();
 80     DNode* head2 = new DNode();
 81     SNode* p1 = head1;
 82     DNode* p2 = head2;
 83     for (int i = 1; i < 10; ++i)
 84     {
 85         SNode* q1 = new SNode(i);
 86         DNode* q2 = new DNode(i);
 87         p1->next = q1;
 88         p1 = q1;
 89         p2->next = q2;
 90         q2->pre = p2;
 91         p2 = q2;
 92     }
 93     cout << "删除前:" << endl;
 94     printList(head1);
 95     printList(head2);
 96 
 97     head1 = DeleteSList(head1, 4);
 98     head2 = DeleteDList(head2, 4);
 99     cout << "删除后:" << endl;
100     printList(head1);
101     printList(head2);
102 
103     return 0;
104 }

 

上一篇:SynchronousQueue源码解析(非公平模式)


下一篇:centos安装redis