LeetCode----LinkedList Ⅰ----C语言

206. Reverse Linked List—Easy

题目

Reverse a singly linked list.

思路

解法一:用前插法创建一个新链表;空间复杂度O(n)
解法二:反向串联旧链表;空间复杂度O(1)

AC代码
解法一:
在这里插入图片描述

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* reverseList(struct ListNode* head) {
    struct ListNode* reverse=NULL;
    struct ListNode* temp;
    
    while(head){
        temp=(struct ListNode* )malloc(sizeof(struct ListNode));
        temp->val=head->val;
        temp->next=reverse;
        reverse=temp;
        head=head->next;
    }
    
    return reverse;
}

解法二:
在这里插入图片描述

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* reverseList(struct ListNode* head) {
    struct ListNode* reverse=NULL;
    struct ListNode* temp;
    
    while(head){
        temp=head;
        head=head->next;
        temp->next=reverse;
        reverse=temp;
    }
    
    return reverse;
}

92. Reverse Linked List II—Medium

不够简洁 记得重构

题目

Reverse a linked list from position m to n. Do it in one-pass.

思路

将链表划分为三段:h1->…->e1 -> h2->…->e2 ->h3->…->e3;
遍历一遍:
需要记录第一段头节点,作为最后返回的结果;
需要记录第一段尾节点,要用来连接下一段;
第二段采用前插法,记录尾节点,用来连接第三段;
注意考虑m==1以及n是最后节点的情况!

AC代码
在这里插入图片描述

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* reverseBetween(struct ListNode* head, int m, int n) {
    struct ListNode* reverse=head;
    struct ListNode* p=head;
    struct ListNode* temp1=NULL;
    struct ListNode* temp2;
    struct ListNode* temp3;
    struct ListNode* temp4;
    int i=1;
    
    while(p){
        if(i==m-1)//记录第一段结尾
            temp4=p;
        if(i==m){
            temp3=p;
            temp1=p;
        } 
        if(i>m&&i<=n){
            temp2=p;
            p=p->next;
            
            temp2->next=temp1;
            temp1=temp2;
            i++;
            continue;
        }
        if(i==n+1){
            temp3->next=p;
            i++;
            break;
        }
        i++;
        p=p->next;
    }
    if(m==1)
        reverse=temp1;
    else
        temp4->next=temp1;
    if(n+1==i)
        temp3->next = NULL;
    return reverse;
}

141. Linked List Cycle—Easy

题目

Given a linked list, determine if it has a cycle in it.
To represent a cycle in the given linked list, we use an integer pos which represents the position (0-indexed) in the linked list where tail connects to. If pos is -1, then there is no cycle in the linked list.

思路

快慢指针
需要注意快指针的下一个指针判空

AC代码

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
bool hasCycle(struct ListNode *head) {
    struct ListNode* slow=head;
    struct ListNode* fast=head;
  
    while(fast&&fast->next){
        slow=slow->next;
        fast=fast->next->next;
        if(slow==fast)
            return true;
    }
    return false;
}

142. Linked List Cycle II—Medium

题目

Given a linked list, return the node where the cycle begins. If there is no cycle, return null.
To represent a cycle in the given linked list, we use an integer pos which represents the position (0-indexed) in the linked list where tail connects to. If pos is -1, then there is no cycle in the linked list.
Note: Do not modify the linked list.

思路

解法一(凭感觉):step1 判断有无环,估计链表长度
step2遍历求结果

解法二:
在这里插入图片描述
如上是快慢指针判断成环单链表的模拟图,我们可得如下等式:
P1+P2+P3+P3+P2+P2=2*(P1+P2)
化简后:P1=2*P3+P2
这个等式的意义:两个同样速度的指针,一个从开头出发,一个从判断成环相等的地方出发,两个指针最后相遇在成环的起始节点。

AC代码
解法一:
在这里插入图片描述

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode *detectCycle(struct ListNode *head) {
    struct ListNode* slow=head;
    struct ListNode* fast=head;
    int sign=0,count=0;
    while(fast&&fast->next){
        slow=slow->next;
        fast=fast->next->next;
        count++;
        if(slow==fast){
            sign=1;
            break;
        }
        
    }
    if(sign==0)
        return NULL;
    
    struct ListNode* p1=head;
    struct ListNode* p2=head;
    
    while(p1){
        for(int i=0;i<=count*2;i++){
            p2=p2->next;
            if(p1==p2){
                sign=0;
                break;
            }
        }
        if(sign==0)
            break;
        p1=p1->next;
    }
    return p1;
}

解法二:
在这里插入图片描述

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode *detectCycle(struct ListNode *head) {
    struct ListNode* slow=head;
    struct ListNode* fast=head;
    int sign=0;
    while(fast&&fast->next){
        slow=slow->next;
        fast=fast->next->next;
        if(slow==fast){
            sign=1;
            break;
        }
    }
    if(sign==0)
        return NULL;
    
    slow=head;
    while(slow!=fast){
        slow=slow->next;
        fast=fast->next;
    }
    return slow;
}

24. Swap Nodes in Pairs—Medium

题目

Given a linked list, swap every two adjacent nodes and return its head.

思路

交换节点值即可

AC代码
在这里插入图片描述

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* swapPairs(struct ListNode* head) {
    if(head==NULL)
        return NULL;
    
    struct ListNode *p1,*p2;
    p1=p2=head;
    
    do{
        p2=p1->next;
        if(p2==NULL)
            break;
        int temp=p1->val;
        p1->val=p2->val;
        p2->val=temp;
    }while(p1=p2->next,p1);
    
    return head;
}

328. Odd Even Linked List—Medium

题目

Given a singly linked list, group all odd nodes together followed by the even nodes. Please note here we are talking about the node number and not the value in the nodes.
You should try to do it in place. The program should run in O(1) space complexity and O(nodes) time complexity.

思路

奇偶位置不同的插入点

AC代码
在这里插入图片描述

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* oddEvenList(struct ListNode* head) {
    if(head==NULL)
        return NULL;
    
    struct ListNode *new,*oddTail,*evenTail,*temp;
    new=oddTail=evenTail=head;
    head=head->next;
    int i=2;
    
    while(head){
        temp=head;
        head=head->next;
        if(i&1){
            temp->next=oddTail->next;
            oddTail->next=temp;
            oddTail=temp;        
        }
        else{
            temp->next=NULL;
            evenTail->next=temp;
            evenTail=temp;
        }
        i++;
    }
    return new;
}

237. Delete Node in a Linked List—Easy

题目

Write a function to delete a node (except the tail) in a singly linked list, given only access to that node.
Given linked list – head = [4,5,1,9], which looks like following:
4 -> 5 -> 1 -> 9

思路

只给出要删除的节点,不知道上一个节点,此节点肯定没法删除;
只能将下一个节点的值给这个节点,然后删除下一个节点。

AC代码
在这里插入图片描述

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
void deleteNode(struct ListNode* node) {
    if(!node||!node->next)
        return;
    node->val=node->next->val;
    node->next=node->next->next;
}

19. Remove Nth Node From End of List—Medium

题目

Given a linked list, remove the n-th node from the end of list and return its head.

思路

双指针:一个先走N+1步,然后另一个再出发,当第一个指针走到链表尾巴时,第二个指针既指向待删除的节点的上一个节点。
注意:可能删除的是第一个节点,此时没法指向该节点上一个节点,此情况拎出来单独考虑!

AC代码
在这里插入图片描述

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* removeNthFromEnd(struct ListNode* head, int n) {
    struct ListNode *p1=head,*p2=NULL;
    int i=0;
    
    while(p1){
        p1=p1->next;
        i++;
        if(i==n+1)
            p2=head;
        if(i>n+1)
            p2=p2->next;
    }
    if(p2)
        p2->next=p2->next->next;
    else
        head=head->next;
    
    return head;
}

83. Remove Duplicates from Sorted List—Easy

题目

Given a sorted linked list, delete all duplicates such that each element appear only once.

思路

解法一:判断当前节点与下一个节点值是否相等,相等删除下一个节点,不相等当前结点更新为下一个节点。
解法二:双指针:第一个指向当前值节点,第二个指针寻找下一个值不等节点。

AC代码
解法一:
在这里插入图片描述

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* deleteDuplicates(struct ListNode* head) {
	if(!head)
        return NULL;
        
    struct ListNode *p=head;
    
    while(p->next){
        if(p->val==p->next->val)
            p->next=p->next->next;
        else
            p=p->next;
    }
    
    return head;
}

解法二:
在这里插入图片描述

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* deleteDuplicates(struct ListNode* head) {
    if(!head)
        return NULL;
    
    struct ListNode *p1,*p2;
    p1=p2=head;
    
    while(p2){
        if(p1->val!=p2->val){
            p1->next=p2;
            p1=p2;
        }
        p2=p2->next;
    }
    if(p1->next&&p1->val==p1->next->val)
        p1->next=NULL;
    
    return head;
}

82. Remove Duplicates from Sorted List II—Medium

出错次数10次

题目

Given a sorted linked list, delete all nodes that have duplicate numbers, leaving only distinct numbers from the original list.

思路

双指针,第一个指针记录第一次遇到的元素,第二个指针指向下一个元素
LOOP:
如果这两个元素不相等,则第一个元素插入新链,更新两个指针
如果这两个元素相等,则第二个指针后移,找到与第一个指针所指元素值不同的元素,使第一个指针指向该元素,第二个指针指向下一个元素
UNTIL 链表遍历结束
注意考虑各种特殊情况

AC代码
在这里插入图片描述

    /**
     * Definition for singly-linked list.
     * struct ListNode {
     *     int val;
     *     struct ListNode *next;
     * };
     */
    struct ListNode* deleteDuplicates(struct ListNode* head) {
        if(head==NULL)
            return NULL;

        struct ListNode *tail,*p1,*temp;
        int sign=1;
        temp=p1=head;
        head=tail=NULL;

        while(p1=p1->next,p1){
            if(p1->val!=temp->val){
                if(sign==1){
                    head=temp;
                    sign=0;
                }
                else
                    tail->next=temp;
                tail=temp;
                tail->next=NULL;
                temp=p1;
            }
            else{
                while(p1=p1->next,p1){
                    if(p1->val!=temp->val)
                        break;
                }
                if(p1==NULL){
                    temp=NULL;
                    break;
                }
                else
                    temp=p1;
            }
        }
        if(temp!=NULL){
            if(sign==1)
                head=temp;
            else{
                tail->next=temp;
                tail=temp;
                tail->next=NULL;
            }
        }
        return head;
    }

猜你喜欢

转载自blog.csdn.net/weixin_43758823/article/details/85145631