链表

链表具有以下性质:

  • 在不考虑分页的情况下,顺序表逻辑上相邻的元素在物理上也相邻

异或链表

异或链表 (Xor Linked List) 也是一种链式存储结构,它可以降低空间复杂度达到和双向链表一样目的,任何一个节点可以方便的访问它的前驱节点和后继结点

题库

反转链表

输入一个链表,反转链表后,输出新链表的表头。

解题思路:使用双链表的方式:

/*
struct ListNode {
   int val;
   struct ListNode *next;
   ListNode(int x) :
         val(x), next(NULL) {
   }
};*/
class Solution {
public:
   ListNode* ReverseList(ListNode* pHead) {
      ListNode* bHead = nullptr;
      ListNode* cur = pHead;
      while(cur){
            ListNode* tmp = cur;
            cur = cur->next;
            tmp->next = bHead;
            bHead = tmp;
      }

      return bHead;
   }
};

判断是否有环

描述:

判断给定的链表中是否有环。如果有环则返回 true,否则返回 false。

你能给出空间复杂度 \(O(1)\) 的解法么?

输入分为 2 部分,第一部分为链表,第二部分代表是否有环,然后回组成 head 头结点传入到函数里面。-1 代表无环,其他的数字代表有环,这些参数解释仅仅是为了方便读者自测调试

按照牛客网的题解,可以使用快慢指针的方式:

/**
* Definition for singly-linked list.
* struct ListNode {
*     int val;
*     ListNode *next;
*     ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
   bool hasCycle(ListNode *head) {
      ListNode* fast = head;
      ListNode* low = head;
      while(low && fast){
            low = low->next;
            if(fast->next) fast = fast->next->next;
            else return false;
            if(low == fast) return true;
      }
      return false;
   }
};

当然了,每次走一步就向下迭代一次的方法也是可以的

单链表排序

给定一个无序单链表,实现单链表的排序 (按升序排序)。

使用插入排序,按照算法导论的思想,将链表分为无序的左手牌和有序的右手牌,每次从左手牌中抽出一张插入右手牌中

/**
* struct ListNode {
*    int val;
*    struct ListNode *next;
* };
*/

class Solution {
public:
   /**
   *
   * @param head ListNode类 the head node
   * @return ListNode类
   */
   ListNode* sortInList(ListNode* head) {
      ListNode* rhs = head;
      head = head->next;
      if(!head) return rhs;
      rhs->next = nullptr;
      while(head){
            auto pos = rhs;
            while(pos->next &&(head->val > pos->next->val) ) pos = pos->next;
            auto tmp = head;
            head = head->next;
            if(tmp->val < rhs->val){
               tmp->next = rhs;
               rhs = tmp;
               continue;
            }
            tmp->next = pos->next;
            pos->next = tmp;
      }
      return rhs;
   }
};

判断是否是回文链表

给定一个链表,请判断该链表是否为回文结构。

按照题解做的。首先用快慢指针将指针移动到链表的中点,然后对链表后半部分进行反转后与之前的链表进行比较。

/**
* struct ListNode {
*    int val;
*    struct ListNode *next;
* };
*/

class Solution {
public:
   /**
   *
   * @param head ListNode类 the head
   * @return bool布尔型
   */
   bool isPail(ListNode* head) {
      ListNode* fast = head;
      ListNode* low = head;
      while(fast && fast->next){
            fast = fast->next->next;
            low = low->next;
      }
      // 如果 fast != nullptr 说明链表的长度是奇数,这时 low->next 不用管
      if(fast) low = low->next;
      fast = ReverseList(low);
      low = head;
      while(fast){
            if(fast->val != low->val) return false;
            fast = fast->next;
            low = low->next;
      }
      return true;
   }
   static ListNode* ReverseList(ListNode* pHead) {
         ListNode* bHead = nullptr;
         ListNode* cur = pHead;
         while(cur){
               ListNode* tmp = cur;
               cur = cur->next;
               tmp->next = bHead;
               bHead = tmp;
         }
         return bHead;
      }
};

常数时间内删除单向链表节点

做三七互娱笔试题碰到的的,思想很简单,就是将下一个节点的值复制到当前节点,然后将下一个节点删除

Last moify: 2022-12-04 15:11:33
Build time:2025-07-18 09:41:42
Powered By asphinx