废话不多说,喊一句号子鼓励自己:程序员永不失业,程序员走向架构!本篇Blog的主题是【查找链表】,使用【链表】这个基本的数据结构来实现,这个高频题的站点是:CodeTop,筛选条件为:目标公司+最近一年+出现频率排序,由高到低的去牛客TOP101去找,只有两个地方都出现过才做这道题(CodeTop本身汇聚了LeetCode的来源),确保刷的题都是高频要面试考的题。
名曲目标题后,附上题目链接,后期可以依据解题思路反复快速练习,题目按照题干的基本数据结构分类,且每个分类的第一篇必定是对基础数据结构的介绍。
链表中倒数第K个节点【EAZY】
与删除倒数第K个节点类似。
题干
需要注意的一点:为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点
解题思路
看到链表的题就可以想到快慢指针,让快指针先走K步,当快指针走到链表结尾时,慢指针基本就在倒数第K个节点,细节上可能会差一两个节点,需要做边界条件判断
- step 1:准备一个快指针,从链表头开始,在链表上先走k步。
- step 2:准备慢指针指向原始链表头,代表当前元素,则慢指针与快指针之间的距离一直都是k。这里需要注意,每次移动前都要做判断,如果还没移动完k步就到了链表末尾,则证明链表长度小于k,返回null
- step 3:快慢指针同步移动,当快指针到达链表尾部的时候,慢指针正好到了倒数k个元素的位置
代码实现
给出代码实现基本档案
基本数据结构:链表
辅助数据结构:无
算法:迭代
技巧:双指针
其中数据结构、算法和技巧分别来自:
- 10 个数据结构:数组、链表、栈、队列、散列表、二叉树、堆、跳表、图、Trie 树
- 10 个算法:递归、排序、二分查找、搜索、哈希算法、贪心算法、分治算法、回溯算法、动态规划、字符串匹配算法
- 技巧:双指针、滑动窗口、中心扩散
当然包括但不限于以上
import java.util.*; /* * public class ListNode { * int val; * ListNode next = null; * public ListNode(int val) { * this.val = val; * } * } */ public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param pHead ListNode类 * @param k int整型 * @return ListNode类 */ public ListNode FindKthToTail (ListNode pHead, int k) { // 1 定义快慢双指针 ListNode fast = pHead; ListNode slow = pHead; // 2 快指针先行k步 for (int i = 0; i < k; i++) { if (fast != null) { // 2-1 如果没到链表尾部,继续前进 fast = fast.next; } else { // 2-1 如果还没走完k步就到链表尾部,说明链表长度小于k,返回null return null; } } // 3 快慢指针同时前进 while (fast != null) { fast = fast.next; slow = slow.next; } return slow; } }
复杂度分析
时间复杂度:遍历了一遍链表,时间复杂度为O(N)
空间复杂度:没有借助外部数据结构,空间复杂度为O(1)