ltx_zero

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

leetcode no.2 两数相加

  • 两个逆序链表加和,只需要按位加,保留进位符,最后到两个空进位空结束
  • 记得每次结束以后让当前链表位指向下一位,处理的和被处理的都是
  • 要将结果头返回,所以要有一个专门的指针用来移位的
  • 前面判断条件是两个链表都非空&&
/**
 * 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*realans=ans;
        int temp=0;
        while(l1!=NULL && l2!=NULL){
            ans->next=new ListNode((l1->val+l2->val+temp)%10);
            temp=(l1->val+l2->val+temp)/10;
            ans=ans->next;
            l1=l1->next;
            l2=l2->next;
        }
        while(l1!=NULL)
        {
            ans->next=new ListNode((l1->val+temp)%10);
            temp=(l1->val+temp)/10;
            l1=l1->next;
            ans=ans->next;
        }
        while(l2!=NULL)
        {
            ans->next=new ListNode((l2->val+temp)%10);
            temp=(l2->val+temp)/10;
            l2=l2->next;
            ans=ans->next;
        }
        if(temp!=0)
        ans->next=new ListNode(temp);
        return realans->next;
    }
};
View Code

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

  • 双指针,让两个的距离为n-1
  • 注意考虑删除的是第一个元素的情况
  • pre指针用来删除的时候用,因此只要指针移动的时候存在就好了
/**
 * 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*temp1=head;
        ListNode*temp2=head;
        ListNode*pre;
        for(int i=1;i<n;i++)
            temp2=temp2->next;
        if(temp2->next==NULL)
            return head->next;
        while(temp2->next!=NULL)
        {
            pre=temp1;
            temp1=temp1->next;
            temp2=temp2->next;
        }
        pre->next=temp1->next;
        return head;
    }
};
View Code

 leetcode no.21 合并两个有序链表

  • 两个不为空就比,为空就连上
  • 可以不新生成节点直接连原来的会更节省内存(因为不用新生成节点),面试学到的,看leetcode标程也是这么说的。。但那个结果显示就很奇怪。。不管了
  • 只有原地调整链表才是o1空间哦,多一个指针,不然反复新生成是要占用的
  • 两条原始链表并不需要保存头,因此可以直接移动指针,不用新加
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        ListNode*temp1=l1;
        ListNode*temp2=l2;
        ListNode*ans=new ListNode(0);
        ListNode*realans=ans;
        while(temp1!=NULL && temp2!=NULL)
        {
            if(temp1->val<=temp2->val)
            {
                ans->next=temp1;
                temp1=temp1->next;
                ans=ans->next;
            }
            else
            {
                ans->next=temp2;
                temp2=temp2->next;
                ans=ans->next;
            }
        }
        if(temp1!=NULL)
            ans->next=temp1;
        if(temp2!=NULL)
            ans->next=temp2;
        return realans->next;
    }
};
View Code

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

  • 类似归并的思路(这个两个两个来再变多的思路叫分治法)
  • 本质上是两个两个合并,然后合成长的在两个合并,降低复杂度到log
  • 调用合并两个升序链表的代码
  • 每次步长是step*2,以二倍的速度增长
  • j每次从0开始,然后下一个j是跨越两倍步长的值,两倍哦!因为step代表的是,同组即将合并的两个之间的距离,那么第二个和下一组第一个也是这个距离,所以是两个,千万不要搞错然后反复合并浪费时间
  • 注意空vector,特判len==0 直接返回NULL
  • 每次保留在较小的下标对应链表中,节省空间哦
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode*mergetwo(ListNode*l1,ListNode*l2)
    {
        ListNode*temp1=l1;
        ListNode*temp2=l2;
        ListNode*ans=new ListNode(0);
        ListNode*realans=ans;
        while(l1 && l2)
        {
            if(l1->val<=l2->val)
            {
                ans->next=l1;
                l1=l1->next;
                ans=ans->next;
            }
            else
            {
                ans->next=l2;
                l2=l2->next;
                ans=ans->next;
            }
        }
        if(l1)
            ans->next=l1;
        if(l2)
            ans->next=l2;
        return realans->next;
    }
    ListNode* mergeKLists(vector<ListNode*>& lists) {
        int len=lists.size();
        if(len==0)
            return NULL;
        for(int step=1;step<=len;step=step*2)
        {
            for(int j=0;j<=len-1;j=j+step*2)
            {
                if(j+step<=len-1)
                lists[j]=mergetwo(lists[j],lists[j+step]);
            }
        }
        return lists[0];
    }
};
View Code

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

  • 前面加一个空节点,从空节点开始pre,之后两个一组如果都不为空就倒置
  • 两个点交换,就是哪个前面连着的新的更新好了,接下来就修改那个,注意最后是pre->next->next,不要手误
  • 返回的结果是空节点的下一个,不要直接返回head,那样会把修改后新的head节点漏掉
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    void change(ListNode*pre)
    {
        ListNode*temp=pre->next;
        pre->next=temp->next;
        temp->next=pre->next->next;
        pre->next->next=temp;
    }
    ListNode* swapPairs(ListNode* head) {
        ListNode*newHead=new ListNode(0);
        newHead->next=head;
        ListNode*pre=newHead;
        while(pre->next!=NULL && pre->next->next!=NULL)
        {
            change(pre);
            pre=pre->next->next;
        }
        return newHead->next;
    }
};
View Code

 

posted on 2020-08-30 19:08  ltx_zero  阅读(156)  评论(0编辑  收藏  举报