• 力扣链表中等难度题


    两数相加

    给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。
    如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。
    您可以假设除了数字 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) {
    ListNode *new1=nullptr;
    ListNode *currentpointer=new1;
    int sum=0;
    int carry=0;
    if(l1==nullptr ) {//倒序,l1.vl==0并不是等于0;
        new1=l2;
        return new1;
    }
    if(l2==nullptr){
        new1=l1;
        return new1;
    }
    while(l1 != NULL || l2 != NULL){//C++中的NULL大写
        sum=0;
        sum+=carry;
        if(l1!=nullptr){
            sum+=l1->val;
            l1=l1->next;
        }
        if(l2!=nullptr){
            sum+=l2->val;
            l2=l2->next;
        }
        
        if(sum>=10){
            
            sum=sum-10;
            carry=1;
        }
        else{
            carry=0;
        }
      ListNode *node=new ListNode(sum);//空指针没有next;
       if(currentpointer ==nullptr)
       {
           currentpointer=node;
           new1=currentpointer;
       }
        else{
      currentpointer->next=node;
        currentpointer=currentpointer->next;
        }
                
            }
            
            if(carry>0){
                ListNode * node = new ListNode(1);//必须新建一个节点类型的指针
                currentpointer->next=node;
            
            }
                return new1;
        }
    };
    

    删除链表中倒数第N个节点

    给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。

    示例:

    给定一个链表: 1->2->3->4->5, 和 n = 2.

    当删除了倒数第二个节点后,链表变为 1->2->3->5.

    说明:

    给定的 n 保证是有效的。

    进阶:

    你能尝试使用一趟扫描实现吗?

    代码

    /**
     * Definition for singly-linked list.
     * struct ListNode {
     *     int val;
     *     ListNode *next;
     *     ListNode(int x) : val(x), next(NULL) {}
     * };
     */
    class Solution {
    public:
        ListNode* removeNthFromEnd(ListNode* head, int n) {
            ListNode *cur=head;
            int length=0;
            while(cur!=NULL)
            {
                length++;
                cur=cur->next;
            }
            cur=head;
            int l=length-n;
            if(l==0){
                head=head->next;
                return head;
            }
            while(l>1)
            {
                cur=cur->next;
                l--;
            }
            cur->next=cur->next->next;
            return head;
        }
    };
    

    进阶一遍遍历代码

    /**
     * Definition for singly-linked list.
     * struct ListNode {
     *     int val;
     *     ListNode *next;
     *     ListNode(int x) : val(x), next(NULL) {}
     * };
     */
    class Solution {
    public:
        ListNode* removeNthFromEnd(ListNode* head, int n) {
            ListNode *kcur=head;
            ListNode *mcur=head;
            while(kcur->next!=NULL &&n>=1){
                kcur=kcur->next;
                n--;
            }
            if(n>=1){
                head=head->next;
                return head;
            }
            else{
                while(kcur->next!=NULL){
                    kcur=kcur->next;
                    mcur=mcur->next;
                }
                mcur->next=mcur->next->next;
            }
          
            
            return head;
        }
    };
    

    题目:删除排序链表的重复节点

    给定一个排序链表,删除所有含有重复数字的节点,只保留原始链表中 没有重复出现 的数字。
    示例 1:

    输入: 1->2->3->3->4->4->5

    输出: 1->2->5

    示例 2:

    输入: 1->1->1->2->3

    输出: 2->3

    代码:

    /**
     * Definition for singly-linked list.
     * struct ListNode {
     *     int val;
     *     ListNode *next;
     *     ListNode(int x) : val(x), next(NULL) {}
     * };
     */
    class Solution {
    public:
        ListNode* deleteDuplicates(ListNode* head) {
            ListNode *p =new ListNode(0);
            p->next=head;
            head=p;
            ListNode*left,*right;
            while(p->next){
                left=p->next;
                right=left;
                while(right->next && right->next->val==left->val)
                    right=right->next;
                if(left==right) p=p->next;
                else p->next = right->next;
            }
            return head->next;
            
        }
    };
    
    // 巧在了增加了一个头结点(0),这样头结点重复也可以删。三个指针,一个负责串联新链表,两个负责排除重复的节点。
    

    题目旋转链表

    给定一个链表,旋转链表,将链表每个节点向右移动 k 个位置,其中 k 是非负数。
    示例 1:

    输入: 1->2->3->4->5->NULL, k = 2

    输出: 4->5->1->2->3->NULL

    解释:

    向右旋转 1 步: 5->1->2->3->4->NULL

    向右旋转 2 步: 4->5->1->2->3->NULL

    示例 2:

    输入: 0->1->2->NULL, k = 4

    输出: 2->0->1->NULL

    解释:

    向右旋转 1 步: 2->0->1->NULL

    向右旋转 2 步: 1->2->0->NULL

    向右旋转 3 步: 0->1->2->NULL

    向右旋转 4 步: 2->0->1->NULL

    代码

    /**
     * Definition for singly-linked list.
     * struct ListNode {
     *     int val;
     *     ListNode *next;
     *     ListNode(int x) : val(x), next(NULL) {}
     * };
     */
    class Solution {
    public:
        ListNode* rotateRight(ListNode* head, int k) {
            ListNode *cur=head;
            if(head ==NULL) return head;//如果指针为空这一行就会爆
            int length = 1;
            while(cur->next!=NULL){//这样循环结束cur正好在尾结点
                length++;
                cur=cur->next;
            }
            int i=k%length;
             i=length-i;
            ListNode *tail =cur;
            tail->next=head;//头结点和尾结点相连
            cur=head;
            while(i>=1){
                if(i==1) tail=cur;//制造出新的尾结点
    //这一块应当是i==2的时候才是尾节点,但是考虑到i初始值为1 ,只能如此赋值
    	            cur=cur->next;
                i--;
            }
            tail->next=NULL;
           
            return cur;
            
            
        }
    };
    

    分割链表

    给定一个链表和一个特定值 x,对链表进行分隔,使得所有小于 x 的节点都在大于或等于 x 的节点之前。
    你应当保留两个分区中每个节点的初始相对位置。
    示例:

    输入: head = 1->4->3->2->5->2, x = 3

    输出: 1->2->2->4->3->5

    代码

    /**
     * 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 *smallist =new ListNode(0);
            ListNode *biglist =new ListNode(0);
            ListNode * node =head,*smallhead=smallist,*bighead=biglist;
            while(node){
                if(node->val <x){
                    smallist ->next=node;
                    smallist=node;
                }
                else {
                    biglist->next=node;
                    biglist=node;
                }
                node =node ->next;
               
                    
                }
            smallist->next=bighead->next;
            biglist->next=NULL;
           ListNode * tmp =smallhead->next;
            //delete smallhead;
           // delete bighead;
            //return smallhead->next;
            return tmp;
            }
        
    };
    

    两种写法竟然速度不一样,但是是常数级别的优化所以不需要考虑

    题目:反转链表II

    反转从位置 m 到 n 的链表。请使用一趟扫描完成反转。
    说明:

    1 ≤ m ≤ n ≤ 链表长度。

    示例:

    输入: 1->2->3->4->5->NULL, m = 2, n = 4

    输出: 1->4->3->2->5->NULL

    代码

    /**
     * Definition for singly-linked list.
     * struct ListNode {
     *     int val;
     *     ListNode *next;
     *     ListNode(int x) : val(x), next(NULL) {}
     * };
     */
    class Solution {
    public:
        ListNode* reverseBetween(ListNode* head, int m, int n) {
            if(head == nullptr || head->next == nullptr){
                return head;
            }
            
            ListNode * left =head;
            for(int i=0;i<m-2;i++){
                left =left->next;
            }
            ListNode *begin=left;
            if(m!=1){
                begin = begin->next;
            }
            ListNode *cur =begin;
            ListNode *mid =cur->next;
            for(int i=0;i<n-m;i++){
                ListNode *temp = mid->next;
                mid->next =cur;
                cur=mid;
                mid=temp;
                if(mid == nullptr){
                    break;
                }
            }
            begin->next =mid;
            if(m!=1){
                left->next =cur;
                return head;
            }
            else{
                return cur;
            }
            
        }
    };
    

    题目:有序链表转换二叉搜索树

    给定一个单链表,其中的元素按升序排序,将其转换为高度平衡的二叉搜索树。

    本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。

    示例:

    给定的有序链表: [-10, -3, 0, 5, 9],
    
    一个可能的答案是:[0, -3, 9, -10, null, 5], 它可以表示下面这个高度平衡二叉搜索树:
    
          0
         / 
       -3   9
       /   /
     -10  5
    

    代码

    /**
     * Definition for a binary tree node.
     * struct TreeNode {
     *     int val;
     *     TreeNode *left;
     *     TreeNode *right;
     *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
     * };
     */
    class Solution {
    public:
        TreeNode* sortedListToBST(ListNode* head) {
            
    //       树一定会用到递归,根节点左右子树-》一层递归的功能,
    //        返回值:树的根节点、
    //        终止条件是:链表遍历到头了
     // 	快慢指针法、DSF
            if(head == NULL ||head ->next==NULL){
                return head ==NULL ? NULL : new TreeNode(head->val);
            }
            ListNode * pre =head ,* mid=head, *fast=head;
            while(fast !=NULL && fast->next!=NULL){
                pre=mid;
                mid=mid->next;
                fast=fast->next->next;
            }
            pre->next=NULL;//左链表尾部
            TreeNode *root=new TreeNode(mid->val);
            root->left= sortedListToBST(head);
            root->right = sortedListToBST(mid->next);
            return root;
            
        }
    };
  • 相关阅读:
    tomcat8.5.57源码阅读笔记2
    tomcat8.5.57源码阅读笔记1
    KVM openstack
    爬虫进阶版
    react 之setChild子组件传值父组件
    Linux找死锁、cpu100%
    Java定时任务
    Java工具类HttpUtil
    Java后台远程下载url文件并远程上传文件
    jQuery上传文件
  • 原文地址:https://www.cnblogs.com/gzyc/p/10692747.html
Copyright © 2020-2023  润新知