20200724

1.剑指offer 24.反转链表

(1)双指针

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */


struct ListNode* reverseList(struct ListNode* head){
    struct ListNode* temp=NULL,*cur=NULL;
    while(head){
        temp=head->next;
        head->next=cur;
        cur=head;
        head=temp;
    }
    return cur;
}

(2)递归

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */


struct ListNode* reverseList(struct ListNode* head){
    // 递归,递归函数返回已反转链表的头结点
    if(head->next==NULL){
        return head;
    }
    struct ListNode* temp=reverseList(head->next);//反转链表的头结点
    //head一直在移动,而temp的位置不变
    head->next->next=head;
    head->next=NULL;
    
    return temp;
}

(3)另一种双指针法

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */


struct ListNode* reverseList(struct ListNode* head){
    // 另一种双指针法
    if(head==NULL) return head;
    struct ListNode* cur=head,*temp=NULL;
    while(head->next){
        temp=head->next->next;
        head->next->next=cur;
        cur=head->next;
        head->next=temp;
    }
    head->next=NULL;
    return cur;
}

最后一种解法参考
https://leetcode-cn.com/problems/fan-zhuan-lian-biao-lcof/solution/fan-zhuan-lian-biao-yi-dong-de-shuang-zhi-zhen-jia/

2.面试题02.01. 移除重复节点

(1)用数组记录每个值出现的次数

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */


struct ListNode* removeDuplicateNodes(struct ListNode* head){
    int numcount[20000];
    memset(numcount,0,sizeof(numcount));
    // struct ListNode* p=head;
    struct ListNode* dummy=(struct ListNode*)malloc(sizeof(struct ListNode));
    dummy->next=head;
    struct ListNode* dummyhead=dummy;
    while(head){
        int index=head->val;
        numcount[index]=numcount[index]+1;
        if(numcount[index]==1){
            dummy->next=head;
            dummy=dummy->next;
        }       
        head=head->next;
    }
    dummy->next=NULL;//没有这句就会返回全部。。。
    return dummyhead->next;
}

(2)如果不使用临时缓冲区,那么就进行两次循环

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */


struct ListNode* removeDuplicateNodes(struct ListNode* head){
    // 两次循环
    struct ListNode *p=head,*q=head;
    while(p){
        q=p;
        while(q && q->next){
            if((q->next->val)==(p->val)){
                //删除和p相同值的节点
                q->next=q->next->next;
            }
            else{
                q=q->next;
            }     
        }
        p=p->next;
    }
    return head;
}

3.剑指offer 52. 两个链表的第一个公共节点

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
    // 双指针
    if(headA==NULL || headB==NULL)
    {
        return NULL;
    }
    struct ListNode* p=headA,*q=headB;
    while(p||q){
        if(p==q){
            return p;
        }
        p=p->next;
        q=q->next;
        if(p==NULL && q==NULL){
            return NULL;
        }
        if(p==NULL){
            p=headB;
        }
        if(q==NULL){
            q=headA;
        } 
    }
    return NULL;
}

或者

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
    // 双指针
    if(headA==NULL || headB==NULL)
    {
        return NULL;
    }
    struct ListNode* p=headA,*q=headB;
    while(p!=q){
        if(p){
            p=p->next;
        }
        else{
            p=headB;
        }
        if(q){
            q=q->next;
        }
        else{
            q=headA;
        }
    }
    return p;
}

4.876.链表的中间结点

(1)快慢指针

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */


struct ListNode* middleNode(struct ListNode* head){
    struct ListNode* fast=head,*slow=head;
    while(fast && fast->next){
        fast=fast->next->next;
        slow=slow->next;
    }
    return slow;
}

5. 206.反转链表

和之前的一样

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */


struct ListNode* reverseList(struct ListNode* head){
    if(head==NULL) return NULL;
    // // 递归
    // if(head->next==NULL){
    //     return head;
    // }
    // struct ListNode *newhead=reverseList(head->next);
    // head->next->next=head;
    // head->next=NULL;
    // return newhead;
    // 迭代
    struct ListNode *tmp=NULL,*cur=NULL;
    while(head){
        tmp=head->next;
        head->next=cur;
        cur=head;
        head=tmp;
    }
    return cur;
}

6. 203.移除链表元素

(1)检查当前结点的下一个结点的val是否等于目标val,如果等于,则更改当前结点的下一个结点为下下个结点。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */


struct ListNode* removeElements(struct ListNode* head, int val){
    if(head==NULL) return NULL;
    while(head && head->val==val){
        head=head->next;
    }
    struct ListNode* prev=head;
    while(prev && prev->next){
        if(prev->next->val==val){
            prev->next=prev->next->next;
        }
        else{
            prev=prev->next;
        }
    }
    return head;
}

(2)递归

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */


struct ListNode* removeElements(struct ListNode* head, int val){
    if(head==NULL) return head;
    // 递归
    if(head->val==val)
    {
        head=removeElements(head->next,val);
    }
    else{
        head->next=removeElements(head->next,val);
    }
    
    return head;
}

7.剑指offer 18.删除链表的节点

和前面的题都差不多

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */


struct ListNode* deleteNode(struct ListNode* head, int val){
    if(head==NULL) return NULL;
    while(head->val==val){
        head=head->next;
        return head;
    }
    struct ListNode *p=head;
    while(p){
        if(p->next->val==val){
            p->next=p->next->next;
            break;
        }
        else{
            p=p->next;
        }
    }
    return head;
}

8. 面试题02.05 链表求和

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */

int listlength(struct ListNode *head){
    int len=0;
    struct ListNode *p=head;
    while(p){
        p=p->next;
        len++;
    }
    return len;
}
struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2){
    int len1=listlength(l1);
    int len2=listlength(l2);
    if(len1<len2){
        //用l1存和,把l1统一成较长的链表
        struct ListNode* temp=l1;
        l1=l2;
        l2=temp;
        int templen=len2;
        len1=len2;
        len2=templen;
    }
    int carry=0;//进位标志
    struct ListNode* res=l1;
    while(l1){
        l1->val=(l1?l1->val:0)+(l2?l2->val:0)+carry;
        carry=(l1->val)/10;
        l1->val=l1->val%10;
        if(l1->next==NULL) break;
        l1=l1?l1->next:0;
        l2=l2?l2->next:0;
    }
    if(carry==1){
        l1->next=(struct ListNode*)malloc(sizeof(struct ListNode));
        l1->next->val=1;
        l1->next->next=NULL;
        //为什么下面的代码不能连上,去掉第36行
        // l1=(struct ListNode*)malloc(sizeof(struct ListNode));
        // l1->val=1;
        // l1->next=NULL;
    }
    return res;
}

在额外添加一个结点进位那里卡了好久,现在也还是不太懂为什么注释的地方的疑问,为什么这样不能把新结点和旧的链表连上。

9. 430.扁平化多级双向链表

(1)使用栈
参考https://leetcode-cn.com/problems/flatten-a-multilevel-doubly-linked-list/solution/bian-ping-hua-duo-ji-shuang-xiang-lian-biao-by-lee/

"""
# Definition for a Node.
class Node(object):
    def __init__(self, val, prev, next, child):
        self.val = val
        self.prev = prev
        self.next = next
        self.child = child
"""

class Solution(object):
    def flatten(self, head):
        """
        :type head: Node
        :rtype: Node
        """
        # 使用栈
        if(head==None):
            return head
        dummy=Node(0,None,head,None)

        stack=[]
        pre=dummy
        cur=head
        stack.append(cur)

        while(stack):
            cur=stack.pop()
            pre.next=cur
            cur.prev=pre

            if(cur.next):
                stack.append(cur.next)

            if(cur.child):
                stack.append(cur.child)
                cur.child=None

            pre=cur

        dummy.next.prev=None

        return dummy.next




    #     # 递归
    #     p=head
    #     while(p->)

    #     return head
    # def dfs(self,head,nexthead):
    #     # 递归
    #     p=head
    #     while(p.child==NULL):
    #         p=p->next
    #     if(p.next==NULL and p.child==NULL):
    #         tail=p;
    #     while(p.child):
    #         nexthead=p.next
    #         q=dfs(p.child,nexthead)
    #         p.next=q
    #         q.prev=p
    #         # p.child=NULL

        
        
    #     tail.next=nexthead
    #     nexthead.prev=tail

    #     return head


(2)dfs

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值