18.<tag-链表和基础题>-面试题 02.01. 移除重复节点 + lt.147.对链表进行插入排序

面试题 02.01. 移除重复节点

[案例需求]

在这里插入图片描述

[思路分析一, 集合容器缓冲法]

  • 在写链表类题目时, 还是要从一个栗子出发, 多用笔在纸上走一遍流程, 这样我们才能对整个代码实现有一个清晰的把握!
  • 对于本题, 我们比较容易借助集合把遍历过的结点数据保存起来, 然后一边遍历一边比较遇到的结点和集合中的数据是否重复, 如果重复的话就把这个节点删除.
  • 因为是涉及到了链表结点的删除, 我们还是用temp.next 去删除结点比较好! 因为我们需要前驱结点嘛;

[代码实现]

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode removeDuplicateNodes(ListNode head) {
        //一边遍历一边比对哈希表
        //发现重复的直接删除链表关系
        //List<Integer> list = new ArrayList<>();
        //注意, hashSet要比list的效率高出特别多!
        Set<Integer> list = new HashSet<>();
        if(head == null)return head;
        list.add(head.val);

        ListNode temp = head;

        while(temp.next != null){
            if(list.contains(temp.next.val)){
                temp.next = temp.next.next;
                //temp = temp.next; //注意本行代码加上的话是不对的, 因为temp.next 在被删除之后, 赋予的是temp.next.next结点, 仍然需要一趟比较操作呢!
            }else{
                list.add(temp.next.val);
                temp = temp.next;
            }
        }
        return head;
    }
}

在这里插入图片描述

//注意, hashSet要比ArrayList的效率高出特别多!
在这里插入图片描述

[思路分析二, ]

  • 进阶法: 不让用额外的空间
  • 那只能时间换空间了, 两个for循环嵌套, 遍历链表, 把相同值的结点删掉一个;
    在这里插入图片描述

[代码实现]

class Solution {
    public ListNode removeDuplicateNodes(ListNode head) {
        ListNode ob = head;
        while (ob != null) {
            ListNode oc = ob;
            while (oc.next != null) {
                if (oc.next.val == ob.val) {
                    oc.next = oc.next.next;
                } else {
                    oc = oc.next;
                }
            }
            ob = ob.next;
        }
        return head;
    }
}

lt. 147. 对链表进行插入排序

[案例需求]

在这里插入图片描述

[思路分析]

在这里插入图片描述

[代码实现]

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode insertionSortList(ListNode head) {
        //插入排序, 无序插入到有序序列;
        //前面是有序的, lastSorted 指示无序的最后一个
        //cur是当前的第一个无序节点
        //遍历时的两种情况
        ///1. lastedSort.val <= cur, 直接有序+1
        //2. 否则, 从头查找无需链表, 找到第一个大与cur.val的结点插入到他的前面即可

        ListNode dummy = new ListNode(-1);
        dummy.next = head;

        if(head.next == null)return head;
        ListNode cur = head.next;
        ListNode lastSorted = head;

        while(cur != null){
            if(lastSorted.val <= cur.val){
                lastSorted = lastSorted.next;
                //cur = lastSorted.next;
            }else{ //最后一个有序的 > cur
                ListNode temp = dummy;

                while(temp.next.val < cur.val){temp = temp.next;}

                lastSorted.next = cur.next;
                cur.next = temp.next;
                temp.next = cur;    
            }
            cur = lastSorted.next;
        } 

        return dummy.next;   
    }
}

还有几道题实在太简单, 不写题解了
在这里插入图片描述

posted @ 2022-05-26 20:29  青松城  阅读(29)  评论(0)    收藏  举报