Java解析剑指Offer链表篇(2)

目录

一、合并两个有序链表

1、题目要求

2、基本思路

3、代码实现 

二、*链表分割 

1、题目要求

2、基本思路

3、代码实现

三、删除链表中重复的结点

 1、题目要求

2、基本思路

3、代码实现


一、合并两个有序链表

1、题目要求

将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。

​​​​​​21. 合并两个有序链表 - 力扣(LeetCode) 

2、基本思路

这个题目给出了两个升序的链表,需要我们合并为一个升序的链表,首先我们可以想到可以建立一个新的结点newHead这个结点来当做新的链表的头结点,然后我们在新建立一个结点temp来记录新的链表头结点后面的结点,然后依次比较两个有序链表中各个结点的大小,依次排序加入到新的链表后面,这边利用了链表的尾插法,最后判断首先遍历完了那个链表,说明另外一个链表还没遍历完,因为每个链表都为升序链表,因此直接把得到的尾结点与没有遍历完的链表部分连接即可。

3、代码实现 

class Solution {
    public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
          if(list1 == null && list2 == null){
              return null;
          }
          ListNode newHead = new ListNode();
          ListNode temp = newHead;
          while(list1 != null&&list2 != null){
              if(list1.val < list2.val){
                  temp.next = list1;
                  list1 = list1.next;
                  temp = temp.next;
              }else{
                  temp.next = list2;
                  list2 = list2.next;
                  temp = temp.next;
              }
          }
          if(list1 == null){
              temp.next = list2;
          }else{
              temp.next = list1;
          }
          return newHead.next;
    }
}

二、*链表分割 

1、题目要求

现有一链表的头指针 ListNode* pHead,给一定值x,编写一段代码将所有小于x的结点排在其余结点之前,且不能改变原来的数据顺序,返回重新排列后的链表的头指针。

链表分割_牛客题霸_牛客网 (nowcoder.com)

2、基本思路

这个题就比较麻烦了,我们可以建立两个区间,一个区间来存储小于X的结点,另外一个来存储大于X的结点,因此需要定义四个结点这四个结点我们定义为null即可,分别为temp1、temp2这俩个结点用来存储小于X的结点,我们定位区间1;temp3、temp4这两个来存储大于X的结点,我们定位区间2 。并且我们需要利用所给的链表头结点pHead来遍历整个链表来和X比较,假如小于X就放在区间1,否则放在区间2。首先假如区间1位第一个结点,则我们需要temp1和temp2与第一个结点相等,后面的结点连在temp2结点后面即可。区间2的操作与区间1相同。

这里我们需要考虑一点,就是,假如我们的区间1或者区间2根本没有结点,怎么办?

因此我们还需要在最后连接两个区间的时候判断一下各自是否为空,要是为空返回另外一个数组即可,还有一点就是在所以干完之后,我们还需要吧最后一个结点的下一个地址为null。

3、代码实现

public class Partition {
    public ListNode partition(ListNode pHead, int x) {
        ListNode temp1 = null;
        ListNode temp2 = null;
         ListNode temp3 = null;
         ListNode temp4 = null;
        while(pHead != null){
            if(pHead.val < x){
                if(temp1 == null){
                    temp1 = pHead;
                    temp2 = pHead;
                }else{
                    temp2.next = pHead;
                    temp2 = temp2.next;
                }
            }else{
                if(temp3 == null){
                    temp3 = pHead;
                    temp4 = pHead;
                }else{
                    temp4.next = pHead;
                    temp4 = temp4.next;
                }
            }
          pHead = pHead.next;
        }
        if(temp1 == null){
            return temp3;
        }
        if(temp3 == null){
            return temp1;
        }
        temp2.next = temp3;
        temp4.next = null;
        return temp1;
        
        // write code here
    }
}

三、删除链表中重复的结点

 1、题目要求

在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表 1->2->3->3->4->4->5  处理后为 1->2->5

数据范围:链表长度满足 0 \le n \le 1000 \0≤n≤1000  ,链表中的值满足 1 \le val \le 1000 \1≤val≤1000

删除链表中重复的结点_牛客题霸_牛客网 (nowcoder.com) 

2、基本思路

这个题我们需要考虑两点问题:(1)这些重复结点不止一个。(2)这些重复结点都是连续的。

因此我们需要建立一个新的链表,然后在去建立一个cur结点去遍历pHead链表,去寻找连续并且重复的结点,因为这些结点都是连续所以我们可以判断当 cur.val == cur.next.val 说明这个两个结点相同,我们就cur = cur.next直接跳过这个结点即可,直到cur.val != cur.next.val时,我们吧这个符合要求的结点直接与新链表连接即可。

到最后切记吧新建链表的尾结点next值置为null,并且返回新链表头结点得next结点。

3、代码实现

public class Solution {
    public ListNode deleteDuplication(ListNode pHead) {
        ListNode newHead = new ListNode(0);
        ListNode temp = newHead;
        ListNode cur = pHead;
        while(cur != null){
            if(cur.next != null && cur.val == cur.next.val){
               while(cur.next !=null && cur.val == cur.next.val){
                   // 跳过值与当前结点相同的全部结点,找到第一个与当前结点不同的结点
                   cur = cur.next;
               }
                cur = cur.next;
            }else{
                temp.next = cur;
                cur = cur.next;
                temp = temp.next;
            }
        }
        temp.next = null;
        return newHead.next;

    }
}

  • 14
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 12
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

跑不死的程序员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值