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

  • 相关阅读:
    解决PKIX:unable to find valid certification path to requested target 的问题
    Linux 上的常用文件传输方式介绍与比较
    用VNC远程图形化连接Linux桌面的配置方法
    红帽中出现”This system is not registered with RHN”的解决方案
    linux安装时出现your cpu does not support long mode的解决方法
    CentOS SSH配置
    es6扩展运算符及rest运算符总结
    es6解构赋值总结
    tortoisegit安装、clon、推送
    es6环境搭建
  • 原文地址:https://www.cnblogs.com/lau1997/p/12817432.html
Copyright © 2011-2022 走看看