zoukankan      html  css  js  c++  java
  • 链表

      ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
            int len1=1;//记录l1的长度
            int len2=1;//记录l2的长度
            ListNode* p=l1;
            ListNode* q=l2;
            while(p->next!=NULL)//获取l1的长度
            {
                len1++;
                p=p->next;
            }
            while(q->next!=NULL)//获取l2的长度
            {
                len2++;
                q=q->next;
            }
            if(len1>len2)//l1较长,在l2末尾补零
            {
                for(int i=1;i<=len1-len2;i++)
                {
                    q->next=new ListNode(0);
                    q=q->next;
                }
            }
            else//l2较长,在l1末尾补零
            {
                for(int i=1;i<=len2-len1;i++)
                {
                    p->next=new ListNode(0);
                    p=p->next;
                }
            }
            p=l1;
            q=l2;
            bool count=false;//记录进位
            ListNode* l3=new ListNode(-1);//存放结果的链表
            ListNode* w=l3;//l3的移动指针
            int i=0;//记录相加结果
            while(p!=NULL&&q!=NULL)
            {
                i=count+p->val+q->val;
                w->next=new ListNode(i%10);
                count=i>=10?true:false;
                w=w->next;
                p=p->next;
                q=q->next;
            }
            if(count)//若最后还有进位
            {
                w->next=new ListNode(1);
                w=w->next;
            }
            return l3->next; 
        }
    };

    给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。

    如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。

    您可以假设除了数字 0 之外,这两个数都不会以 0 开头。

    示例:

    输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
    输出:7 -> 0 -> 8
    原因:342 + 465 = 807

    /**
     * Definition for singly-linked list.
     * struct ListNode {
     *     int val;
     *     ListNode *next;
     *     ListNode(int x) : val(x), next(NULL) {}
     * };
     */
    class Solution {
    public:
        ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
            int a=0,c=0,b=0;
            ListNode* p=l1;
            ListNode* q=l2;
            ListNode* ne=new ListNode(0,nullptr);
            ListNode* w=ne;
            while(p!=NULL&&q!=NULL)
            {
                c=(p->val+q->val)+b;
                w->next=new ListNode(c%10);
                b=c/10;
                w=w->next;
                p=p->next;
                q=q->next;
            }
            while(p==NULL&&q!=NULL)
            {
                c=q->val+b;
                w->next=new ListNode(c%10);
                b=c/10;
                w=w->next;
                q=q->next;
            }
            while(q==NULL&&p!=NULL)
            {
                c=p->val+b;
                w->next=new ListNode(c%10);
                b=c/10;
                w=w->next;
                p=p->next;
            }
            if(b)
            {w->next=new ListNode(1);
             w=w->next;}
            return ne->next;
    
        }
    }

    /**
     * Definition for singly-linked list.
     * struct ListNode {
     *     int val;
     *     ListNode *next;
     *     ListNode(int x) : val(x), next(NULL) {}
     * };
     */
    class Solution {
    public:
        ListNode* partition(ListNode* head, int x) {
             ListNode* big = new ListNode(-1);
             ListNode* let = new ListNode(-1);
             ListNode *ret = let,*da = big;
             while(head != NULL){
                 if(head->val < x){
                     let->next = head;
                     let = let->next;
                 }else{
                     big->next = head;
                     big = big->next;
                 }
                 head = head->next;
             }
             big->next = NULL;
             let->next = da->next;
             return ret->next;
        }
    };

    解题步骤
    建立快指针p和慢指针q,记n的初始值为in
    快指针p先走,同时变量n自减
    当n自减到0时,p已经比慢指针q先走了in步,此后两个指针开始同步移动
    当p指向NULL时,遍历结束,循环体不再执行,故此时p刚好比q多走了in+1步,直接删除q的后一结点即可
    特殊情况分析:需要删除头节点时,p最多只会比q多走n步,q并未移动,这与删除倒数第n-1个结点的情况是一样的,不过这种情况下n只会自减到0,直接返回头结点的下一个结点即可

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

    方法一:迭代
    假设存在链表 1 → 2 → 3 → Ø,我们想要把它改成 Ø ← 1 ← 2 ← 3。

    在遍历列表时,将当前节点的 next 指针改为指向前一个元素。由于节点没有引用其上一个节点,因此必须事先存储其前一个元素。在更改引用之前,还需要另一个指针来存储下一个节点。不要忘记在最后返回新的头引用!

    Java

    public ListNode reverseList(ListNode head) {
    ListNode prev = null;
    ListNode curr = head;
    while (curr != null) {
    ListNode nextTemp = curr.next;
    curr.next = prev;
    prev = curr;
    curr = nextTemp;
    }
    return prev;
    }


    复杂度分析

    时间复杂度:O(n),假设 nn 是列表的长度,时间复杂度是 O(n)。
    空间复杂度:O(1)。
    方法二:递归
    递归版本稍微复杂一些,其关键在于反向工作。假设列表的其余部分已经被反转,现在我该如何反转它前面的部分?

    public ListNode reverseList(ListNode head) {
    if (head == null || head.next == null) return head;
    ListNode p = reverseList(head.next);
    head.next.next = head;
    head.next = null;
    return p;
    }

    复杂度分析

    时间复杂度:O(n),假设 nn 是列表的长度,那么时间复杂度为 O(n)。
    空间复杂度:O(n),由于使用递归,将会使用隐式栈空间。递归深度可能会达到 nn 层。

  • 相关阅读:
    读《奇点临近》
    C++中rand()函数的用法
    第四届蓝桥杯 c/c++真题
    ACM做题过程中的一些小技巧
    树状数组
    go单元测试进阶篇
    浓缩的才是精华:浅析GIF格式图片的存储和压缩
    腾讯IVWEB团队:WebRTC 点对点直播
    Mongodb Geo2d索引原理
    Unity编译Android的原理解析和apk打包分析
  • 原文地址:https://www.cnblogs.com/lau1997/p/12817432.html
Copyright © 2011-2022 走看看