剑指OFFER练习记录(三. 链表)

剑指OFFER练习记录(三. 链表)

这是自己刷题的笔记, 有Java和Python的实现, 尽量每一题都挑选典型的方法进行记录. 题目的分类是按照牛客平台分类的.

从尾到头打印链表

题目:
输入一个链表,按链表从尾到头的顺序返回一个ArrayList。

思路:
可以用栈来存储每一个节点的数据, 遍历完链表后取出打印.或者对链表进行翻转, 到尾部时翻转回来并打印

import java.util.ArrayList;
import java.util.Stack;
public class Solution {
    public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {

        Stack<Integer> help = new Stack<>();
        ArrayList<Integer> res = new ArrayList<>();

        while (listNode != null){
            help.add(listNode.val);
            listNode = listNode.next;
        }
        while (!help.isEmpty()){
            res.add(help.pop());
        }

        return res;
    }
}

翻转链表

class Solution:
    # 返回从尾部到头部的列表值序列,例如[1,2,3]
    def printListFromTailToHead(self, listNode) -> list:
        res = []
        if listNode is None:
            return res

        pre = None
        while listNode is not None:
            nxt = listNode.next
            listNode.next = pre
            pre = listNode
            listNode = nxt


        listNode = pre
        pre = None
        while listNode is not None:
            res.append(listNode.val)
            nxt = listNode.next
            listNode.next = pre
            pre = listNode
            listNode = nxt
        
        return res

入口环结点

题目:
给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。

思路:
可以利用哈希表记录沿途的节点值, 遍历链表, 如果哈希表中有该值表是环的入口结点
或者
利用快慢指针遍历链表

  • 快指针走两步, 慢指针走一步
  • 当快慢指针相遇时, 快指针回到链表的头部
  • 继续遍历, 当快慢指针相遇时, 此时指针指向的就是入口结点
public class Solution {
    public ListNode EntryNodeOfLoop(ListNode pHead) {
        if (pHead == null || pHead.next == null || pHead.next.next == null) {
            return null;
        }

        ListNode n1 = pHead.next;
        ListNode n2 = pHead.next.next;

        while (n1 != n2) {
            // 如果快指针指向了空结点, 或者无环链表的最后一个结点, 此时链表无环
            if (n2.next == null || n2.next.next == null) {
                return null;
            }
            n2 = n2.next.next;
            n1 = n1.next;
        }


        n2 = pHead;
        while (n1 != n2) {
            n1 = n1.next;
            n2 = n2.next;
        }
        return n1;

    }
}

利用哈希集合记录结点是否已经出现

class Solution:
    def EntryNodeOfLoop(self, pHead):
        node_set = set()
        while pHead is not None:
            if pHead.val in node_set:
                return pHead
            node_set.add(pHead.val)
            pHead = pHead.next

        return None

排序链表删除重复结点

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

思路:
设置一个递归函数, 传入的参数是链表的头部, 返回值是链表的结点, 这个结点的特点是它与下一个结点不重复. 也就是说是第一个不重复的结点.

public class Solution {
    public ListNode deleteDuplication(ListNode pHead) {
        if (pHead == null || pHead.next == null) { // 只有0个或1个结点,则返回
            return pHead;
        }

        if (pHead.val == pHead.next.val) { // 当前结点是重复结点
            ListNode pNode = pHead.next;
            while (pNode != null && pNode.val == pHead.val) {
                // 跳过值与当前结点相同的全部结点,找到第一个与当前结点不同的结点
                pNode = pNode.next;
            }
            return deleteDuplication(pNode); // 从第一个与当前结点不同的结点开始递归
        } else { // 当前结点不是重复结点
            pHead.next = deleteDuplication(pHead.next); // 保留当前结点,从下一个结点开始递归, 并将其接到当前结点的后边
            return pHead;
        }
    }
}

class Solution:
    def deleteDuplication(self, pHead):
        # write code here
        if pHead is None or pHead.next is None:
            return pHead

        if pHead.val == pHead.next.val:
            pNode = pHead.next
            while pNode is not None and pHead.val == pNode.val:
                pNode = pNode.next
            # 找到这个不重复的结点后, 重新进行递归操作
            return self.deleteDuplication(pNode)
        else:
            pHead.next = self.deleteDuplication(pHead.next)
            return pHead
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 链表 记录《剑指offer》中所有关于链表的题目,以及LeetCode中的相似题目 相关题目列表 题目 链表是面试...
    wenmingxing阅读 1,183评论 0 11
  • 1. 找出数组中重复的数字 题目:在一个长度为n的数组里的所有数字都在0到n-1的范围内。数组中某些数字是重复的,...
    BookThief阅读 1,824评论 0 2
  • 基本概念 链表的含义: 链表是一种用于存储数据集合的数据结构,具有以下属性 相邻元素之间通过指针相连 最后一个元素...
    古剑诛仙阅读 1,025评论 0 3
  • 转载请注明出处:http://www.jianshu.com/p/c65d9d753c31 在上一篇博客《数据结构...
    Alent阅读 3,541评论 4 74
  • (一)LeetCode206.反转链表 题目描述: 反转一个单链表。 代码实现 (二)LeetCode160. 相...
    Jarily阅读 1,417评论 0 5