ltx_zero

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

leetcode no.2 两数相加

  • 题目内容为求两个逆序链表的和(首位是个位数,越大越往后)
  • 直接加就可以,留一个存进位的
  • 只要l1,l2,tempnum里面有一个不是空,就要再存进去一个数字
  • 记得执行完以后->next
  • 有可能存在0,所以 每轮的tempnum%10即使是0也要存的
  • 如果已在struct里面给出了构造,那么ListNode*temp=new ListNode就不行了,就得ListNode*temp=new ListNode(0);
/**
 * 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*ans=new ListNode(0);
        ListNode*anstemp=new ListNode(0);
        anstemp=ans;
        int tempnum=0;
        while(l1!=NULL || l2!=NULL||tempnum)
        {
            if(l1)
            {
                tempnum+=l1->val;
                l1=l1->next;
            }
            if(l2)
            {
                tempnum+=l2->val;
                l2=l2->next;
            }
            ListNode*tempnode=new ListNode(tempnum%10);
            anstemp->next=tempnode;
            tempnum=tempnum/10;
            anstemp=anstemp->next;
        }
        return ans->next;
    }
};
View Code

 leetcode no.19 删除链表的倒数第N个节点

  • 给好的是头就有数据的链表,因此pre->next=head这样比较合适
  • 特判遇到删除头节点的情况
  • 在找完数字然后找的过程,因为node的起始点进循环就node->next,所以temp=num-n+1以后还要-1(序列五个数字,倒数第二个,正数4,但是只在循环走三次)
/**
 * 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) {
        if(head->next==NULL)
            return NULL;
        ListNode*tail=new ListNode(0);
        ListNode*pre=new ListNode(0);
        tail=head;
        int num=0;
        while(tail->next!=NULL)
        {
            num++;
            tail=tail->next;
        }
        num++;
        ListNode*node=new ListNode(0);
        node=head;
        pre->next=head;
        if(n==num)
            return head->next;
        int temp=num+1-n;
        for(int i=1;i<=temp-1;i++)
        {
            node=node->next;
            pre=pre->next;
        }
        pre->next=node->next;
        delete node;
        return head;
    }
};
View Code

 leetcode no.19 更优秀的做法

  • 一轮遍历,使用两个指针,两个指针中间隔着n-2个数,即end先走n-1次,之后两个同步移动直至end走到尾巴上
  • 注意删除是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*first=new ListNode(0);
        ListNode*end=new ListNode(0);
        first=head;
        end=head;
        ListNode*pre=new ListNode(0);
        pre->next=head;
        int num=1;
        while(num<=n-1)
        {
            num++;
            end=end->next;
        }
        if(end->next==NULL)
            return head->next;
        while(end->next!=NULL)
        {
            first=first->next;
            end=end->next;
            pre=pre->next;
        }
        pre->next=first->next;
        delete first;
        return head;
    }
};
View Code

 leetcode no.23 合并k个排序链表

  • 注意特判整个vector空的情况
  • 里面每个链表都走到尽头退出循环
  • 注意!所有涉及到链表的题目一定要一个ans存结果。一个temp不断temp->next
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* mergeKLists(vector<ListNode*>& lists) {
        ListNode*ans=new ListNode(0);
        ListNode*temp=new ListNode(0);
        if(lists.empty())
            return ans->next;
        temp=ans;
        int minnum=10000;
        int mindown=-1;
        bool notempty=true;
        while(notempty)
        {
            notempty=false;
            mindown=-1;
            minnum=10000;
            for(int i=0;i<=lists.size()-1;i++)
            {
                if(lists[i]!=NULL)
                {
                    notempty=true;
                    if(lists[i]->val<minnum)
                    {
                        minnum=lists[i]->val;
                        mindown=i;
                    }
                }
            }
            if(!notempty)
                break;
            temp->next=new ListNode(lists[mindown]->val);
            temp=temp->next;
            lists[mindown]=lists[mindown]->next;
        }
        return ans->next;
    }
};
View Code

 leetcode no.23合并k个排序链表

  • 可以采用分治的方法,每次计算两个链表,步长每次扩大而
  • 注意空的情况,这时候访问lists[0]也是违规的
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode*merge(ListNode*l1,ListNode*l2)
    {
        if(l1==NULL)
            return l2;
        if(l2==NULL)
            return l1;
        ListNode*ans=new ListNode(0);
        ListNode*temp=new ListNode(0);
        temp=ans;
        while(l1 && l2)
        {
            if(l1->val<=l2->val)
            {
                ListNode*p=new ListNode(l1->val);
                l1=l1->next;
                temp->next=p; 
                temp=temp->next;  
            }
            else
            {
                ListNode*p=new ListNode(l2->val);
                l2=l2->next;
                temp->next=p;
                temp=temp->next;
            }
        }
        if(l1)
        temp->next=l1;
        if(l2)
        temp->next=l2;
        return ans->next;
    }
    ListNode* mergeKLists(vector<ListNode*>& lists) {
        if(lists.empty()==true)
         return NULL;
        for(int step=1;step<=lists.size();step=step*2)
        {
            for(int i=0;i<=lists.size()-1;i=i+step)
            {
                if(i+step<=lists.size()-1)
                lists[i]=merge(lists[i],lists[i+step]);
            }
        }
        return lists[0];
    }
};
View Code

 leetcode no.24两两交换链表中的节点

  • 如果只有一个或者为空直接返回
  • 前面两个节点的交换要拉出来,因为head发生变化要存储返回值
  • 后面的节点要存好pre是交换前的最后一个点,head代表当前要交换的第一个点
  • pre->next=head->next head->next=pre->next->next pre->next->next=head 保持原则,一个被用完了以后立即修改
  • 前两个点里面:newhead=head->next head->next=newhead->next newhead->next=head newhead成为新的起点。
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* swapPairs(ListNode* head) {
        if(head==NULL||head->next==NULL)
            return head; 
        ListNode*newHead=new ListNode(0);
        newHead=head->next;
        head->next=newHead->next;
        newHead->next=head;
        ListNode*temp=new ListNode(0);
        temp=head;
        while(temp->next!=NULL && temp->next->next!=NULL)
        {
            head=temp->next;
            temp->next=head->next;
            head->next=temp->next->next;
            temp->next->next=head;
            temp=head;
        }
        return newHead;
    }
};
View Code

 leetcode no.25 K个一组翻转链表(修改指针指向的方法)

  • 注意如果刚好有k个,是需要反转的,即使后面没有了
  • count和nownode每次是对应的。指向这组的第几个点count就是几
  • prev标记的是k个一组这个组前一个点,nownode在next以后是k个一组的下一个点,中间的就是k个区间
  • 中间的每次修改next的指向
  • k个找到以后,执行k-1轮,因为最后一轮需要和prev单独标记,此时的cur指向k个一组的原来的最后一个点
  • 如果是第一组,那么需要修改head为cur的值
  • 不是第一组,那么prev->next=就是最后cur
  • 这组中第一个点的next是newnode
  • 新一轮的prev是这一组原始的第一个点,是需要标记好的,新一轮的cur就是nownode
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* reverseKGroup(ListNode* head, int k) {
        ListNode*cur=new ListNode(0);
        ListNode*pre=new ListNode(0);
        ListNode*next=new ListNode(0);
        ListNode*nownode=new ListNode(0);
        ListNode*prev=new ListNode(0);
        ListNode*temp=new ListNode(0);
        bool pd=true;
        int count=1;
        cur=head;
        nownode=head;
        prev=NULL;
        while(nownode!=NULL)
        {
            if(count==k)
            {
                nownode=nownode->next;
                if(cur==head)
                    pd=true;
                pre=nownode;
                temp=cur;
                for(int i=1;i<k;i++)
                {
                    next=cur->next;
                    cur->next=pre;
                    pre=cur;
                    cur=next;
                }
                if(pd)
                {
                    head=cur;
                    pd=false;
                }
                if(prev!=NULL)
                    prev->next=cur;
                prev=temp;
                //temp=cur->next;
                cur->next=pre;
                cur=nownode;
                count=1;
            }
            else
            {
                count++;
                nownode=nownode->next;
            }
        }
        return head;
    }
};
View Code

 leetcode no.61 旋转链表

  • 链表后移k个单位,如果k大于len就取余
  • 双指针移动,对应temp2就是尾节点,next接原始头
  • temp1是倒数第k个点,是新的head
  • pre是新的尾节点
  • 注意k等于0的时候,不需要转动,这样必须直接返回,不能进到下面,不然pre会有问题。
  • 需要修改的点是,修改以后选temp1为新的head,原来的尾节点temp2加next是原来的head,新的head前面最后一个点pre的next成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) {
        if(head==NULL)
            return head;
        ListNode*temp1=new ListNode(0);
        ListNode*temp2=new ListNode(0);
        temp1=head;temp2=head;
        int len=0;
        while(temp1!=NULL)
        {
            len++;
            temp1=temp1->next;
        }
        k=k%len;
        if(k==0)
            return head;
        for(int i=1;i<=k-1;i++)
            temp2=temp2->next;
        ListNode*pre=new ListNode(0);
        pre->next=head;
        temp1=head;
        while(temp2->next!=NULL)
        {
            pre=pre->next;
            temp1=temp1->next;
            temp2=temp2->next;
        }
        temp2->next=head;
        pre->next=NULL;
        return temp1;
    }
};
View Code

 

posted on 2020-03-18 19:07  ltx_zero  阅读(147)  评论(0编辑  收藏  举报