力扣链表中等难度题

两数相加

给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。
如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。
您可以假设除了数字 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;
        
    }
};
posted @ 2019-04-11 21:33  差生_G  阅读(468)  评论(0编辑  收藏  举报