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 层。

  • 相关阅读:
    Power of Cryptography
    Radar Installation
    Emag eht htiw Em Pleh
    Help Me with the Game
    89. Gray Code
    87. Scramble String
    86. Partition List
    85. Maximal Rectangle
    84. Largest Rectangle in Histogram
    82. Remove Duplicates from Sorted List II
  • 原文地址:https://www.cnblogs.com/lau1997/p/12817432.html
Copyright © 2011-2022 走看看