leetcode练习

本文介绍了解决两个链表问题的方法:相加两个数字表示的链表及从链表末尾删除指定位置的节点。通过具体实例展示了算法实现过程。

导语

这是两道关于链表的习题,不算难题,但是有很多需要注意的小细节,在这里记录一下

Add Two Numbers

You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list.

You may assume the two numbers do not contain any leading zero, except the number 0 itself.

Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)
Output: 7 -> 0 -> 8

分析:题目翻译翻译过来就是:给你两个非空链表,表示两个非负整数。数字以相反的顺序存储,每个节点包含一个数字。 添加这两个数字并将其作为链接列表返回。
您可以假定这两个数字不包含任何前导零,除了数字0本身。

简单来说就是用两个链表来表示两个数字,链表中每个节点中存储一位数。需要做的就是按照加法规则,将链表中每个节点的数字相加,并将每一位存储在一个新链表中。
解决方法:按照从低位开始相加,设置进位标记,有进位的就进位。

需要注意的特殊情况:链表长度不一致;加到最高位时存在进位。整体逻辑比较简单,但是特别需要注意细节的处理。
下面是我解决这道题的方法:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2) {
   struct ListNode *p,*per,*a;
    int carry=0;//标记进位 
    p=(struct ListNode*)malloc(sizeof(struct ListNode));
    int temp=l1->val+l2->val;
    p->val=(temp)%10;
    l1=l1->next;l2=l2->next; 
    p->next=NULL;//一个空链表 
    per=p;
    if(temp>=10) carry=1;

    while(l1&&l2){
     /**
     *两个链表都存在的情况下,按照逐位相加的方法进行运算
     *注意每次相加后都要判断是否存在需要进位的情况
     */
        int s=0;//逐位加法 
        s=l1->val;l1=l1->next;
        s+=l2->val; l2=l2->next; 

        if(carry){
            s+=1;
            carry=0;
        }

        if(s>=10) carry=1;//保存进位 

        a=(struct ListNode*)malloc(sizeof(struct ListNode));
        a->val=s%10;
        a->next=per->next;
        per->next=a;
        per=a;
    }

    while(l1){
        /**
        *只剩下l1的情况下,将l1相加
        */
        int s=0;
        s=l1->val+carry;l1=l1->next;
        if(s>=10)
            carry=1;
        else
            carry=0;
        a=(struct ListNode*)malloc(sizeof(struct ListNode));
        a->val=s%10;
        a->next=per->next;
        per->next=a;
        per=a;
    }

    while(l2){
        int s=0;
        s=l2->val+carry;l2=l2->next;
        if(s>=10)
            carry=1;
        else
            carry=0;
        a=(struct ListNode*)malloc(sizeof(struct ListNode));
        a->val=s%10;
        a->next=per->next;
        per->next=a;
        per=a;
    }
    /**
    *最后一定记得判断是否还有进位没有处理
    */
     if(carry){
        a=(struct ListNode*)malloc(sizeof(struct ListNode));
        a->val=1;
        a->next=per->next;
        per->next=a;
        per=a;
    }
    return p; 
}

Remove Nth Node From End of List

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

For example,

Given linked list: 1->2->3->4->5, and n = 2.

After removing the second node from the end, the linked list becomes 1->2->3->5.

Note:
Given n will always be valid.
Try to do this in one pass.

给定一个链表,从列表的最后删除第n个节点并返回它的头部。

例如,

    给定链表:1-> 2-> 3-> 4-> 5,并且n = 2。

    从最后删除第二个结点后,链表将变为1-> 2-> 3-> 5。
分析:这道题目需要注意的一个地方是链表为空的情况下,返回一个空链表,另外的主要问题就是找到从后面数起的第n个结点。
下面是我的方法:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* removeNthFromEnd(struct ListNode* head, int n) {
    struct ListNode *p=head,*per=head;
   if(head == NULL || head->next == NULL)  
        return NULL;  

    for(int i = 0;i < n;i++)  
        per = per->next;  
    if(per == NULL)  
        return head->next;  
    while(per->next != NULL)  
    {  
        per = per->next;  
        p = p->next;  
    }  
    p->next = p->next->next;  

    return head;
}

思路是:因为是要找从后面数起的第n位,所以用了一个per来辅助寻找第n个结点,首先让per移位到从头结点起的第n+1位,然后让per结点移动到尾结点的位置,同时P从头结点开始移动,当per移动到尾结点是,p刚好移动到要删除位置的前一位。然后就是很简单的删除再返回链表就可以了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值