当前位置: 首页 > article >正文

基于链表的基础笔试/面试题

1. 反转链表

问题描述:反转一个单向链表。

示例:

输入:1 → 2 → 3 → 4 → 5

输出:5 → 4 → 3 → 2 → 1

class ListNode {
    int val;
    ListNode next;
    ListNode(int x) {
        val = x;
    }
}

public class LinkedList {
    public ListNode reverseList(ListNode head) {
        ListNode prev = null;
        ListNode curr = head;
        while (curr != null) {
            ListNode nextTemp = curr.next; // 保存下一个节点
            curr.next = prev;              // 当前节点反转指向前一个节点
            prev = curr;                   // prev移动到当前节点
            curr = nextTemp;               // curr移动到下一个节点
        }
        return prev; // prev为新的头节点
    }
}

2. 查找链表中间节点

问题描述:给定一个单链表,找出链表的中间节点。如果链表有两个中间节点,则返回第二个中间节点。

示例:

输入:[1, 2, 3, 4, 5]

输出:3

输入:[1, 2, 3, 4, 5, 6]

输出:4

public class LinkedList {
    public ListNode middleNode(ListNode head) {
        ListNode slow = head;
        ListNode fast = head;
        while (fast != null && fast.next != null) {
            slow = slow.next;        // 慢指针每次走一步
            fast = fast.next.next;   // 快指针每次走两步
        }
        return slow;  // 当快指针到达尾部时,慢指针正好在中间
    }
}

3. 环形链表检测

问题描述:给定一个链表,判断链表是否有环。

示例:

输入:[3, 2, 0, -4],环形链表,从节点2开始有环

输出:true

public class LinkedList {
    public boolean hasCycle(ListNode head) {
        if (head == null) return false;
        
        ListNode slow = head;
        ListNode fast = head;
        
        while (fast != null && fast.next != null) {
            slow = slow.next;        // 慢指针每次走一步
            fast = fast.next.next;   // 快指针每次走两步
            
            if (slow == fast) {      // 快慢指针相遇,表示有环
                return true;
            }
        }
        return false;  // 没有环
    }
}

4. 删除链表倒数第N个节点

问题描述:删除链表的倒数第N个节点,并返回链表的头节点。

示例:

输入:[1, 2, 3, 4, 5], N = 2

输出:[1, 2, 3, 5]

public class LinkedList {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode fast = head;
        ListNode slow = head;
        
        // 快指针先走n步
        for (int i = 0; i < n; i++) {
            fast = fast.next;
        }
        
        // 如果fast为null,说明要删除的是头节点
        if (fast == null) {
            return head.next;
        }
        
        // 快慢指针同时走
        while (fast != null && fast.next != null) {
            fast = fast.next;
            slow = slow.next;
        }
        
        // 删除慢指针的下一个节点
        slow.next = slow.next.next;
        return head;
    }
}

5. 合并两个有序链表

问题描述:将两个升序链表合并为一个新的升序链表,返回合并后的链表。

示例:

输入:1 → 2 → 4, 1 → 3 → 4

输出:1 → 1 → 2 → 3 → 4 → 4

public class LinkedList {
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        ListNode dummy = new ListNode(0);  // 创建一个虚拟头节点
        ListNode current = dummy;
        
        while (l1 != null && l2 != null) {
            if (l1.val < l2.val) {
                current.next = l1;
                l1 = l1.next;
            } else {
                current.next = l2;
                l2 = l2.next;
            }
            current = current.next;
        }
        
        // 将剩余的部分连接上
        if (l1 != null) {
            current.next = l1;
        }
        if (l2 != null) {
            current.next = l2;
        }
        
        return dummy.next;  // 返回合并后的链表头
    }
}

6. 删除链表中的重复元素

问题描述:给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次。

示例:

输入:1 → 1 → 2 → 3 → 3

输出:1 → 2 → 3

public class LinkedList {
    public ListNode deleteDuplicates(ListNode head) {
        ListNode current = head;
        
        while (current != null && current.next != null) {
            if (current.val == current.next.val) {
                current.next = current.next.next;  // 跳过重复节点
            } else {
                current = current.next;  // 继续遍历
            }
        }
        
        return head;
    }
}

7. 找到链表的环入口节点

问题描述:给定一个链表,如果链表中有环,找出环的入口节点。如果没有环,返回null。

示例:

输入:3 → 2 → 0 → -4,环形链表,环的入口是节点2

输出:2

public class LinkedList {
    public ListNode detectCycle(ListNode head) {
        ListNode slow = head;
        ListNode fast = head;
        
        // 快慢指针检测是否有环
        while (fast != null && fast.next != null) {
            slow = slow.next;
            fast = fast.next.next;
            
            if (slow == fast) {  // 如果快慢指针相遇,说明有环
                ListNode entry = head;
                while (entry != slow) {  // 找环的入口
                    entry = entry.next;
                    slow = slow.next;
                }
                return entry;  // 返回环的入口节点
            }
        }
        return null;  // 没有环
    }
}


上述是一些面试中常见问题,还有一部分比较少见但是也会遇上的问题:

  1. 链表的交集:如何找到两个链表的交集?

  2. 链表的差集:如何找到两个链表的差集?

  3. 链表的环形数组:如何判断一个链表是否可以构成环形数组?

  4. 复制带有随机指针的链表:如何复制一个包含随机指针的链表?

  5. 奇偶排序链表:如何对链表进行奇偶排序?

  6. 链表的插入排序:如何使用插入排序算法对链表进行排序?

  7. 链表的递归遍历:如何使用递归方法遍历链表?

  8. 链表的扁平化:如何将一个嵌套的链表扁平化?

  9. 链表的旋转:如何将链表向右旋转k个位置?

  10. 链表的重新排列:如何将链表中的节点重新排列,使得奇数索引的节点和偶数索引的节点交替出现?

  11. 链表的分组:如何将链表中的节点分成k个大小相等的组?

  12. 链表的压缩:如何压缩链表,使得所有值为val的节点合并为一个节点?

可以试着实现这些笔试题,在面试时更有自信!!!

不积跬步,无以至千里 --- xiaokai


http://www.kler.cn/a/418500.html

相关文章:

  • 树莓派2安装jupyterlab以便更好的编程体验
  • Nature Methods | 人工智能在生物与医学研究中的应用
  • 斐波那契数
  • “harmony”整合不同平台的单细胞数据之旅
  • webpack(react)基本构建
  • atoi函数的模拟实现
  • Qt-界面优化QSS
  • 即时通讯| IM+RTC在AI技术加持下的社交体验
  • spaCy 入门与实战:强大的自然语言处理库
  • springboot(20)(删除文章分类。获取、更新、删除文章详细)(Validation分组校验)
  • API 与 SDK 之间的区别
  • QUAD-MxFE平台
  • 【LeetCode】3208.交替组II
  • 基于PHP的香水销售系统的设计与实现
  • Qt自定义 Qt Designer 插件
  • 使用Python OpenCV实现图像形状检测
  • C语言——指针基础
  • MySQL中什么是脏读、幻读、不可重复读
  • 使用java操作Parquet文件
  • http(请求方法,状态码,Cookie与)
  • C#高级教程
  • Arrays.asList()新增报错,该怎么解决
  • 云原生周刊:K8s 严重漏洞
  • AI智能体与代理IP:携手共创智能网络新时代
  • ts解决vite unplugin-auto-import/vite
  • 【自动化】配置信息抽取