当前位置:   article > 正文

手撕链表——多方法解决链表面试题_链表面试手撕

链表面试手撕

一、链表的快慢指针问题

例题:

本题就是快慢指针问题,读题得要找到中间节点,我们的第一个反应是先遍历得到节点个数n,在走n/2步即可走到中间节点,但是如果数据过于庞大,就要处理多步,此时引入快慢指针,解题思路就是定义两个指针,快的走两步,慢的走一步,当快的走向空时,那么慢的就一定是走到中点。

代码如下:

  1. public ListNode middleNode(ListNode head) {
  2. if(head == null || head.next == null){
  3. return head;
  4. }else {
  5. ListNode fir = head;
  6. ListNode sec = head;
  7. while (fir != null && fir.next != null){
  8. fir = fir.next.next;
  9. sec = sec.next;
  10. }return sec;
  11. }
  12. }

例题:

 

 此题与上一题的思路大相径庭,要找到倒数第k个节点的值,那么,就让快指针先走k步,然后快慢指针一起走,当快指针走到空时,那么慢指针一定就走到了倒数的第k个节点,返回值即可。

代码如下:

  1. public int kthToLast(ListNode head, int k) {
  2. ListNode fast = head;
  3. ListNode slow = head;
  4. for(int i = 0; i < k ; i++){
  5. fast = fast.next;
  6. }
  7. while(fast != null){
  8. fast = fast.next;
  9. slow = slow.next;
  10. }
  11. return slow.val;
  12. }

二、环形链表问题

例题:

环形链表我们可以借用操场跑圈的问题,在日常生活中,跑的快的同学,总是能够越过一圈追上跑得慢的同学,由此我们可以定义两个指针,让快指针一次走两步,慢指针一次走一步,此时,如果有快指针等于了慢指针的时刻,那么一定是环形链表,反之则不是。

代码如下:

  1. public boolean hasCycle(ListNode head) {
  2. if(head == null || head.next == null){
  3. return false;
  4. }
  5. else {
  6. ListNode fast = head;
  7. ListNode low = head;
  8. while (fast != null && fast.next != null){
  9. fast = fast.next.next;
  10. low = low.next;
  11. if (fast == low){
  12. return true;
  13. }
  14. }
  15. }
  16. return false;
  17. }

例题:

 本题与上一题的区别是要返回入环的节点,那么如何找到入环的节点呢???此时就牵扯到了数学问题,以下是我画图分析的:

根据表达式得到 当快慢指针相遇,在原处重新引入一个新指针,当他走到B点时一定会与慢指针相遇,那么直接返回节点即可,代码如下:

  1. public ListNode detectCycle(ListNode head) {
  2. if (head == null || head.next == null){
  3. return null;
  4. }else {
  5. ListNode fast = head;
  6. ListNode low = head;
  7. while (fast != null && fast.next !=null){
  8. fast = fast.next.next;
  9. low = low.next;
  10. if(fast == low){
  11. ListNode cur = head;
  12. while (cur != low){
  13. cur = cur.next;
  14. low = low.next;
  15. }
  16. return low;
  17. }
  18. }
  19. }
  20. return null;
  21. }

三、反转链表问题

例题:

 反转我介绍两种方法,遍历算法以及递归算法

遍历:新链表,采用头插入方法遍历原链表即可得到反转后链表

代码如下:

  1. public ListNode reverseList(ListNode head) {
  2. if(head == null || head.next == null){
  3. return head;
  4. }else{
  5. ListNode prev = null;
  6. ListNode cur = head;
  7. while (cur != null){
  8. ListNode next = cur.next;
  9. cur.next = prev;
  10. prev = cur;
  11. cur = next;
  12. }
  13. return prev;
  14. }
  15. }

递归:结合方法语义,输入一个链表我们就能得到一个反转的链表,此时记住第二个节点,反转后,让第二个节点指向头节点,头节点指向空,反转后的新节点为头节点。

代码如下:

  1. public ListNode reverseList(ListNode head) {
  2. if(head == null || head.next == null){
  3. return head;
  4. }else {
  5. ListNode x = head.next;
  6. ListNode newHead = reverseList(head.next);
  7. x.next = head;
  8. head.next = null;
  9. return newHead;
  10. }
  11. }

四、删除链表重复元素

例题:

代码如下:

  1. public ListNode deleteDuplicates(ListNode head) {
  2. if (head == null || head.next == null) {
  3. return head;
  4. } else {
  5. ListNode prev = head;
  6. ListNode cur = head.next;
  7. while (cur != null) {
  8. if (prev.val != cur.val) {
  9. cur = cur.next;
  10. prev = prev.next;
  11. } else {
  12. while (cur != null && prev.val == cur.val) {
  13. cur = cur.next;
  14. }
  15. prev.next = cur;
  16. prev = prev.next;
  17. }
  18. }
  19. }
  20. return head;
  21. }

 例题:

代码如下: 

  1. public ListNode deleteDuplicates(ListNode head) {
  2. ListNode dummyHead = new ListNode();
  3. dummyHead.next = head;
  4. ListNode prev = dummyHead;
  5. ListNode cur = prev.next;
  6. while (cur != null) {
  7. ListNode net = cur.next;
  8. if (net == null) {
  9. break;
  10. } else {
  11. if (cur.val != net.val) {
  12. prev = prev.next;
  13. cur = cur.next;
  14. }else {
  15. while (net != null && cur.val == net.val) {
  16. net = net.next;
  17. }
  18. prev.next = net;
  19. cur = net;
  20. }
  21. }
  22. }return dummyHead.next;
  23. }

五、总结

     以上就是链表中常见的一些问题,解题方法大多是大同小异,最重要的还是掌握解题思路,这样会少走一些弯路!!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/661701
推荐阅读
相关标签
  

闽ICP备14008679号