一 链表中倒数第k个节点

题目描述:

输入一个链表,输出该链表中倒数第k个结点

问题分析:

一句话概括:

两个指针一个指针p1先开始跑,指针p1跑到k-1个节点后,另一个节点p2开始跑,当p1跑到最后时,p2所指的指针就是倒数第k个节点。

思想的简单理解:

前提假设:链表的结点个数(长度)为n。

规律一:要找到倒数第k个结点,需要向前走多少步呢?比如倒数第一个结点,需要走n步,那倒数第二个结点呢?很明显是向前走了n-1步,所以可以找到规律是找到倒数第k个结点,需要向前走n-k+1步。

算法开始:

1. 设两个都指向head的指针p1和p2,当p1走了k-1步的时候,停下来。p2之前一直不动。

2. p1的下一步是走第k步,这个时候,p2开始一起动了。至于为什么p2这个时候动呢?看下面的分析。

3. 当p1走到链表的尾部时,即p1走了n步。由于我们知道p2是在p1走了k-1步才开始动的,也就是说p1和p2永远差k-1步。所以当p1走了n步时,p2走的应该是在n-(k-1)步。即p2走了n-k+1步,此时巧妙的是p2正好指向的是规律一的倒数第k个结点处。

这样是不是很好理解了呢?

考察内容:

链表+代码的鲁棒性

示例代码:

  1. /*
  2. //链表类
  3. public class ListNode {
  4. int val;
  5. ListNode next = null;
  6. ListNode(int val) {
  7. this.val = val;
  8. }
  9. }*/
  10. //时间复杂度O(n),一次遍历即可
  11. public class Solution {
  12. public ListNode FindKthToTail(ListNode head,int k) {
  13. ListNode pre=null,p=null;
  14. //两个指针都指向头结点
  15. p=head;
  16. pre=head;
  17. //记录k值
  18. int a=k;
  19. //记录节点的个数
  20. int count=0;
  21. //p指针先跑,并且记录节点数,当p指针跑了k-1个节点后,pre指针开始跑,
  22. //当p指针跑到最后时,pre所指指针就是倒数第k个节点
  23. while(p!=null){
  24. p=p.next;
  25. count++;
  26. if(k<1){
  27. pre=pre.next;
  28. }
  29. k--;
  30. }
  31. //如果节点个数小于所求的倒数第k个节点,则返回空
  32. if(count<a) return null;
  33. return pre;
  34. }
  35. }

二 反转链表

题目描述:

输入一个链表,反转链表后,输出链表的所有元素。

问题分析:

链表的很常规的一道题,这一道题思路不算难,但自己实现起来真的可能会感觉无从下手,我是参考了别人的代码。

思路就是我们根据链表的特点,前一个节点指向下一个节点的特点,把后面的节点移到前面来。

就比如下图:我们把1节点和2节点互换位置,然后再将3节点指向2节点,4节点指向3节点,这样以来下面的链表就被反转了。

考察内容:

链表+代码的鲁棒性

示例代码:

  1. /*
  2. public class ListNode {
  3. int val;
  4. ListNode next = null;
  5. ListNode(int val) {
  6. this.val = val;
  7. }
  8. }*/
  9. public class Solution {
  10. public ListNode ReverseList(ListNode head) {
  11. ListNode next = null;
  12. ListNode pre = null;
  13. while (head != null) {
  14. //保存要反转到头来的那个节点
  15. next = head.next;
  16. //要反转的那个节点指向已经反转的上一个节点
  17. head.next = pre;
  18. //上一个已经反转到头部的节点
  19. pre = head;
  20. //一直向链表尾走
  21. head = next;
  22. }
  23. return pre;
  24. }
  25. }

三 合并两个排序的链表

题目描述:

输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。

问题分析:

我们可以这样分析:

1. 假设我们有两个链表 A,B;

2. A的头节点A1的值与B的头结点B1的值比较,假设A1小,则A1为头节点;

3. A2再和B1比较,假设B1小,则,A1指向B1;

4. A2再和B2比较。。。。。。。

就这样循环往复就行了,应该还算好理解。

考察内容:

链表+代码的鲁棒性

示例代码:

非递归版本:

  1. /*
  2. public class ListNode {
  3. int val;
  4. ListNode next = null;
  5. ListNode(int val) {
  6. this.val = val;
  7. }
  8. }*/
  9. public class Solution {
  10. public ListNode Merge(ListNode list1,ListNode list2) {
  11. //list1为空,直接返回list2
  12. if(list1 == null){
  13. return list2;
  14. }
  15. //list2为空,直接返回list1
  16. if(list2 == null){
  17. return list1;
  18. }
  19. ListNode mergeHead = null;
  20. ListNode current = null;
  21. //当list1和list2不为空时
  22. while(list1!=null && list2!=null){
  23. //取较小值作头结点
  24. if(list1.val <= list2.val){
  25. if(mergeHead == null){
  26. mergeHead = current = list1;
  27. }else{
  28. current.next = list1;
  29. //current节点保存list1节点的值因为下一次还要用
  30. current = list1;
  31. }
  32. //list1指向下一个节点
  33. list1 = list1.next;
  34. }else{
  35. if(mergeHead == null){
  36. mergeHead = current = list2;
  37. }else{
  38. current.next = list2;
  39. //current节点保存list2节点的值因为下一次还要用
  40. current = list2;
  41. }
  42. //list2指向下一个节点
  43. list2 = list2.next;
  44. }
  45. }
  46. if(list1 == null){
  47. current.next = list2;
  48. }else{
  49. current.next = list1;
  50. }
  51. return mergeHead;
  52. }
  53. }

递归版本:

  1. public ListNode Merge(ListNode list1,ListNode list2) {
  2. if(list1 == null){
  3. return list2;
  4. }
  5. if(list2 == null){
  6. return list1;
  7. }
  8. if(list1.val <= list2.val){
  9. list1.next = Merge(list1.next, list2);
  10. return list1;
  11. }else{
  12. list2.next = Merge(list1, list2.next);
  13. return list2;
  14. }
  15. }

(4)剑指Offer之链表相关编程题的更多相关文章

  1. 剑指offer(36-40)编程题

    两个链表的第一个公共结点 数字在排序数组中出现的次数 二叉树的深度 平衡二叉树 数组中只出现一次的数字 36.输入两个链表,找出它们的第一个公共结点. class Solution1 { public ...

  2. 剑指offer(41-45)编程题

    41.入一个递增排序的数组和一个数字S,在数组中查找两个数,是的他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的. class Solution { public: vector&l ...

  3. 《剑指offer》 链表中倒数第k个节点

    本题来自<剑指offer> 链表中倒数第k个节点 题目: 输入一个链表,输出该链表中倒数第k个结点. 思路: 倒数第k个节点,而且只能访问一遍链表,定义两个节点,两者之间相差k个距离,遍历 ...

  4. 剑指Offer:链表中环的入口节点【23】

    剑指Offer:链表中环的入口节点[23] 题目描述 给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null. 题目分析 第一步确定链表中是否包含环,怎么确定呢?我们定义两个指针橙和 ...

  5. 剑指Offer:链表中倒数第k个结点【22】

    剑指Offer:链表中倒数第k个结点[22] 题目描述 输入一个链表,输出该链表中倒数第k个结点. 解题思考 我们定义两个指针L和R,R事先移动K-1个位置,然后两者同时往后移动直到遇到R的下个节点为 ...

  6. 剑指 Offer 22. 链表中倒数第k个节点

    剑指 Offer 22. 链表中倒数第k个节点 Offer 22 常规解法 常规解法其实很容易可以想到,只需要先求出链表的长度,然后再次遍历取指定长度的链接即可. package com.walega ...

  7. 力扣 - 剑指 Offer 22. 链表中倒数第k个节点

    题目 剑指 Offer 22. 链表中倒数第k个节点 思路1(栈) 既然要倒数第k个节点,那我们直接把所有节点放到栈(先进后出)里面,然后pop弹出k个元素就可以了 代码 class Solution ...

  8. 【剑指Offer】链表中倒数第k个节点 解题报告(Python)

    [剑指Offer]链表中倒数第k个节点 解题报告(Python) 标签(空格分隔): LeetCode 题目地址:https://www.nowcoder.com/ta/coding-intervie ...

  9. 【剑指Offer】链表中环的入口结点 解题报告(Python)

    [剑指Offer]链表中环的入口结点 解题报告(Python) 标签(空格分隔): 剑指Offer 题目地址:https://www.nowcoder.com/ta/coding-interviews ...

随机推荐

  1. excel copy cell & batch operation & checkbox

    excel copy cell & batch operation & checkbox excel 右下角,下拉/双击 (复制 cell) 注意: 不是选择列

  2. 阿里中间件RocketMQ

    阿里RocketMQ是怎样孵化成Apache顶级项目的? RocketMQ 迈入50万TPS消息俱乐部 Apache RocketMQ背后的设计思路与最佳实践 专访RocketMQ联合创始人:项目思路 ...

  3. HDU4497——GCD and LCM

    这个题目挺不错的,看到是通化邀请赛的题目,是一个很综合的数论题目. 是这样的,给你三个数的GCD和LCM,现在要你求出这三个数有多少种可能的情况. 对于是否存在这个问题,直接看 LCM%GCD是否为0 ...

  4. 【bzoj3125】CITY 插头dp

    题目描述 给出一个n*m的矩阵,某些格子不能通过,某些格子只能上下通过或左右通过.求经过所有非不能通过格子的哈密顿回路条数. 输入 第一行有两个数N, M表示地图被分割成N*M个块,接下来有N行,每行 ...

  5. 【数据库_Postgresql】实体类映射问题之不执行sql语句

    后台controller到dao都没问题,前台页面接收的是一个实体类对象,在service层接收的也是对象,传入mapper里面的也是对象,没有用map,但是打印台却不执行sql语句,也没有明显错误提 ...

  6. The Toll! Revisited UVA - 10537(变形。。)

    给定图G=(V,E)G=(V,E),VV中有两类点,一类点(AA类)在进入时要缴纳1的费用,另一类点(BB类)在进入时要缴纳当前携带金额的1/20(不足20的部分按20算) 已知起点为SS,终点为TT ...

  7. WPF 如何加载图片

    Uri ri = new Uri(AppDomain.CurrentDomain.BaseDirectory + "Resources/exp.jpg"); ImageSource ...

  8. codeforces 217E 【Alien DNA】

    倒序考虑每一个操作,对于一个操作$[l, r]$,他产生的影响区间将是$[r+1,r + r + l - 1]$,如果$r+l-1>K$的话,$K$之后的区间我们是不关心的. 暴力扫描这个区间 ...

  9. 驱动之LCD的介绍与应用20170209

    本文主要介绍的是LCD的介绍与应用,直接看个人笔记即可:

  10. Oracle 解决【ORA-01704:字符串文字太长】(转)

    错误提示:oracle在toad中执行一段sql语句时,出现错误‘ORA-01704:字符串文字太长’.如下图: 原因:一般为包含有对CLOB字段的数据操作.如果CLOB字段的内容非常大的时候,会导致 ...