链表-1

 

21. 合并两个有序链表

struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2){
        if(!l1) return l2;
        else if(!l2) return l1;

        struct ListNode *head=(struct ListNode*)malloc(sizeof(struct ListNode));
        struct ListNode * t=head;

        while (l1 && l2){
		if (l1->val < l2->val){
			t->next = l1;
			l1 = l1->next;
		}			
		else{//令人迷惑,这里要是加上else if的判断条件,就会出错??什么原理??
			t->next = l2;
			l2 = l2->next;
		}			
		t = t->next;		
	}
        if(l1) t->next=l1;
        else t->next=l2;
        return head->next;
}

链表-1_第1张图片 

83. 删除排序链表中的重复元素 

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

    while(t!=NULL&&t->next!=NULL){        
        if(t->next->val==t->val){//判断条件前后顺序不同执行用时不同
            p=t->next;  //不写释放内存的语句会更快
           // t->next=p->next;此句引起错误的原因是,使用空指针p,不应该用即将释放的指针
            t->next=t->next->next;
            free(p);
        }else t=t->next;
    }
    return head;
}

链表-1_第2张图片 

141. 环形链表(快慢相遇)

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 一个快指针(next两步)一个慢指针(next一步),如果环了肯定会相遇
 */
bool hasCycle(struct ListNode *head) {
    if(!head) return false;

    struct ListNode *slow=head,*fast=head;

    while(slow&&fast&&fast->next){
        slow=slow->next;
        fast=fast->next->next;//不用担心越界,while条件里保证了可以访问到两个next
        if(fast==slow) return true;
    }
    return false;
}

链表-1_第3张图片 

图解相交链表 C

  • 消除长度差的思想是,让长的那个链表减去比短的链表多出的那一部分,使两链表长度相同,然后开始遍历

  • 而大神的代码是增加一段距离,使两个新的链表长度相等,然后从起点同时遍历,不管在什么位置,两链表剩余长度都是相同的如图

  • - pa pb一起出发,pa走完了a表就开始走b表,pb相同

    - 当出现pa==pb时,说明出现了交点

链表-1_第4张图片

### 解题思路
这里是对大神代码(复杂化)虽然更易懂(但是惭愧..))
意思是:
- pa pb一起出发,pa走完了a表就开始走b表,pb相同
- 当出现pa==pb时,说明出现了交点

### 代码

```c
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
    if(!headA||!headB) return NULL;

    struct ListNode *pa=headA,*pb=headB;

    while(pa!=pb){//遍历判断相等吗?相等就是交点
        // pa=pa == NULL?headB:pa->next;
        // pb=pb == NULL?headA:pb->next;
        pa=pa;//pa在变化所以每次重新赋值
        if(pa==NULL) pa=headB;//如果pa是空的说明a表走完了,接下来走b表(pa变了)
        else pa=pa->next;//如果pa不空说明a表没走完,那就继续走(pa变了)

        pb=pb;
        if(pb==NULL) pb=headA;
        else pb=pb->next;
    }
    return pa;    
}

链表-1_第5张图片 

203 移除链表元素

解题思路

  • 没有头结点的链表噢

  • 如果上来的前面几个节点就是要删的节点,直接指针后移,并且改变头指针(删除开始节点)

  • 如果不是开头的节点,那么(删除中间节点的方法)

  • 如果没找到相等的节点,那么就一直找下去

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* removeElements(struct ListNode* head, int val){
    struct ListNode *p=head;

    while(p){
        if(p->val==val){ p=p->next;head=p;}//删开头
        else if(p->next&&p->next->val==val) p->next=p->next->next;//删中间
        else p=p->next;
    }
    return head;
}

链表-1_第6张图片

你可能感兴趣的:(leetcode)