链表的相关题目

自己定义一个链表结点结构体

// 单链表
struct ListNode {
    int val;  // 节点上存储的元素
    ListNode *next;  // 指向下一个节点的指针
    ListNode(int x) : val(x), next(NULL) {}  // 节点的构造函数 给val的赋值为x,next的下一个结点指向了空
};

获取第index点的值,我之前的想法是定义一个k。让k++,直到k=index,有一个更简便的方法让index--,让指针移动。

 // 获取到第index个节点数值,如果index是非法数值直接返回-1, 注意index是从0开始的,第0个节点就是头结点
    int get(int index) {
        if (index > (_size - 1) || index < 0) {
            return -1;
        }
        LinkedNode* cur = _dummyHead->next;
        while(index--){ // 如果--index 就会陷入死循环
            cur = cur->next;
        }
        return cur->val;
    }

反转链表,定义两个指针,cur和pre,改变cur->next的指向

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode *pre;
        pre=NULL;//初始化空是因为第一个结点翻转后是最后一个结点,最后一个结点是指向空的
        ListNode *temp;
        while(head)
        {
         
        temp=head->next;
        head->next=pre;//翻转
         pre=head;//移动
        head=temp;
       
        }
        return pre;





    }
};

相邻2个结点互换(简单的模拟过程)

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* swapPairs(ListNode* head) {
        ListNode *newnode=new ListNode(0);
        newnode->next=head;
        ListNode* cur=newnode;
       
        while(cur->next!=NULL&&cur->next->next!=NULL)
        {
            ListNode* temp=cur->next;
            ListNode* temp1=cur->next->next->next;
            cur->next=cur->next->next;
            cur->next->next=temp;
            temp->next=temp1;


            cur=cur->next->next;//每次移动2个结点
        }
        return newnode->next;

    }
};

删除倒数第几个指针,双指针经典用法

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        ListNode *first=new ListNode(0);
        first->next=head;
        ListNode *fast=first;
        ListNode *slow=first;
        while(n--&&fast!=NULL)
        {
            fast=fast->next;
           
        }
        fast=fast->next;//让fast多走一个,这样slow指向的就是被删除的上一个结点方便操作
        while(fast!=NULL)
        {
            slow=slow->next;
            fast=fast->next;
        }
         ListNode *temp;
         temp=slow->next;
         slow->next=temp->next;
         delete temp;
         return first->next;//为什么不返回head 万一头结点被删了呢 



    }
};

查找2个链表相交的点

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        ListNode *first1=new ListNode(0);
        ListNode *first2=new ListNode(0);
        first1->next=headA;
        first2->next=headB;
        ListNode *cur1=first1;
        ListNode *cur2=first2;
        int a=0;//指向同一个结点 地址相同 要给他赋初值 没赋初值过不了
        while(first1->next!=NULL)
        {
            a++;
            first1=first1->next;

        }
        int b=0;//分别求链表长度 长度之差
        while(first2->next!=NULL)
        {
            b++;
            first2=first2->next;
        }
        if(a>b)
        {
            int c=a-b;
            while(c>0)
            {
                cur1=cur1->next;
                c--;
            }
        }
        else 
        {
            int d=b-a;
            while(d>0)
            {
                cur2=cur2->next;
                d--;
            }
        }/* 判断a,b可以简化的算法
        if(a<b)
        {
            swap(a,b);交换a,b的值 交换之后a就b大了
            swap(cur1,cur2);
        }
        int c=a-b;
        while(c--)
        {
            cur1=cur1->next; 两个链表的指针对齐
        }
        
        
        
        */
        while(cur1->next!=NULL&&cur2->next!=NULL)
        {
            if(cur1->next==cur2->next)
            {
                return cur1->next;
                
            }
            cur1=cur1->next;
            cur2=cur2->next;
        }
        
        return NULL;
        
    }
};

环形链表(快慢指针相遇必有环)

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        //判断有环 判断环入口 第一次相遇必在环中
       // ListNode *first=new ListNode(0);
       // first->next=head; 这几步好像没必要
        ListNode *slow=head;
        ListNode *fast=head;
        
        
           
        while(fast!=NULL&&fast->next!=NULL)
        {
             slow=slow->next;
            fast=fast->next->next;
            if(slow==fast)
            {
                ListNode *cur1=head;
                ListNode *cur2=fast;
                while(cur1!=cur2)
                {
                    
                    cur1=cur1->next;
                    cur2=cur2->next;
                }
                return cur2;
            }
            //slow=slow->next;放在前面是因为要先让指针移动起来 因为如果不移动都从头结点开始 slow肯定等于fast
            //fast=fast->next->next;

        }
        return NULL;

    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值