学习完单链表后趁热打铁做了几道面试题。(点击链接可以查看上一篇单链表学习)
以下1-5题难度依次递增,每道题的思路和实现过程将详细的展示。
- 求单链表中节点的个数
- 查找单链表中的倒数第k个节点【新浪面试题】
- 单链表的反转 【腾讯面试题】
- 从尾到头打印单链表【百度,要求方式1:反向遍历,方式2:Stack栈】
- 合并两个有序的单链表,合并之后的链表依然有序
完成每道题之前,可以通过自己的理解去完成,下面我仅说出我的思路分析和代码的实现过程
01求单链表中节点的个数
思路分析:
1.判断是否为空
2.循环遍历——如果辅助节点的next不等于null 就length++
具体代码:
/**
* @param head 头节点
* @return 返回的是单链表有效节点的个数
*/
public static int findSingleLinkLength(HeroNode head) {
//辅助节点
HeroNode cur = head.next;
if (cur == null) {
return 0;
}
//定义一个变量接收节点的个数
int length = 0;
while (cur != null) {
//后移 接着遍历寻找
cur = cur.next;
length++;
}
return length;
}
代码测试:
public class SingleLinkedListDemo {
public static void main(String[] args) {
SingleLinkedList singleLinkedList = new SingleLinkedList();
HeroNode hero1 = new HeroNode(1, "宋江", "及时雨");
HeroNode hero2 = new HeroNode(2, "卢俊义", "玉麒麟");
HeroNode hero3 = new HeroNode(3, "吴用", "智多星");
HeroNode hero4 = new HeroNode(4, "林冲", "豹子头");
HeroNode hero5 = new HeroNode(5, "李逵", "黑旋风");
//添加英雄
singleLinkedList.add(hero1);
singleLinkedList.add(hero3);
singleLinkedList.add(hero5);
singleLinkedList.add(hero2);
//测试单链表有效节点的个数
int length = findSingleLinkLength(singleLinkedList.getHead());
System.out.println("length=" + length);
}
}
测试结果:
length=4
02查找单链表中的倒数第k个节点【新浪面试题】
思路分析:
1.通过(总节点数-目标节点数)去循环遍历
例如: 一共4个节点 现在要查找倒数第3个节点 做法是通过循环(4-3)此找到此节点,其中4是通过调用方法 findSingleLinkLength得到,3为用户传入的数值。
具体代码:
//查找单链表中倒数第K个节点【新浪面试】
public static HeroNode findHeroNode(HeroNode head, int no) {
//定义辅助节点指向第一个节点
HeroNode cur = head.next;
//找出总的节点数
int size = findSingleLinkLength(head);
//对传入的no进行校验
//不存在倒数第0个节点的说法 也不存在要查找的节点数大于总节点数
if (no <= 0 || no > size) {
return null;
}
//循环遍历 假如 3个节点 查找倒数第二个节点 3-2=1
for (int i = 0; i < size - no; i++) {
//后移
cur = cur.next;
}
return cur;
}
代码测试:
public class SingleLinkedListDemo {
public static void main(String[] args) {
SingleLinkedList singleLinkedList = new SingleLinkedList();
HeroNode hero1 = new HeroNode(1, "宋江", "及时雨");
HeroNode hero2 = new HeroNode(2, "卢俊义", "玉麒麟");
HeroNode hero3 = new HeroNode(3, "吴用", "智多星");
HeroNode hero4 = new HeroNode(4, "林冲", "豹子头");
HeroNode hero5 = new HeroNode(5, "李逵", "黑旋风");
//添加英雄
singleLinkedList.add(hero1);
singleLinkedList.add(hero3);
singleLinkedList.add(hero5);
singleLinkedList.add(hero2);
//测试单链表中倒数第K个节点
int no = 3;
HeroNode heroNode = findHeroNode(singleLinkedList.getHead(), no);
System.out.printf("倒数第%d节点", no);
System.out.println(heroNode);
}
}
测试结果:
倒数第3个节点HeroNode{no=3, name=‘吴用’, nickname=‘智多星’}
03单链表的反转 【腾讯面试题】
思路分析:
1.先定义一个节点 HeroNode reverse = new HeroNode(0,"","");
2.从头到尾遍历原来的链表,每遍历一个节点,就将其取出,并放在新的链表reverseHead的最前端
3.原来的链表的head.next = reverseHead.next
//单链表的反转
public static void reverseSingleLink(HeroNode head) {
//没有节点或者只存在一个节点
if (head.next == null || head.next.next == null) {
return;
}
//创建一个新的单链表
HeroNode reverseHead = new HeroNode(0,"","");
//定义一个辅助变量,帮助我们遍历原来的链表
HeroNode cur = head.next;
HeroNode next = null;//指向当前节点的下一个节点
while (cur != null) {
//保留当前节点的下一个节点
next = cur.next;
//cur的下一个节点指向新链表的前端
cur.next = reverseHead.next;
//将cur连接到新的链表上
reverseHead.next = cur;
cur = next;//节点后移
}
//将 head.next 指向 reverseHead.next 实现单链表的反转
head.next = reverseHead.next;
}
代码测试:
public class SingleLinkedListDemo {
public static void main(String[] args) {
SingleLinkedList singleLinkedList = new SingleLinkedList();
HeroNode hero1 = new HeroNode(1, "宋江", "及时雨");
HeroNode hero2 = new HeroNode(2, "卢俊义", "玉麒麟");
HeroNode hero3 = new HeroNode(3, "吴用", "智多星");
HeroNode hero4 = new HeroNode(4, "林冲", "豹子头");
HeroNode hero5 = new HeroNode(5, "李逵", "黑旋风");
//添加英雄
singleLinkedList.add(hero1);
singleLinkedList.add(hero3);
singleLinkedList.add(hero5);
singleLinkedList.add(hero2);
System.out.println("反转前的链表");
singleLinkedList.list();
System.out.println("测试反转后的链表");
reverseSingleLink(singleLinkedList.getHead());
singleLinkedList.list();
}
}
测试结果:
反转前的链表
HeroNode{no=1, name=‘宋江’, nickname=‘及时雨’}
HeroNode{no=3, name=‘吴用’, nickname=‘智多星’}
HeroNode{no=5, name=‘李逵’, nickname=‘黑旋风’}
HeroNode{no=2, name=‘卢俊义’, nickname=‘玉麒麟’}
测试反转后的链表
HeroNode{no=2, name=‘卢俊义’, nickname=‘玉麒麟’}
HeroNode{no=5, name=‘李逵’, nickname=‘黑旋风’}
HeroNode{no=3, name=‘吴用’, nickname=‘智多星’}
HeroNode{no=1, name=‘宋江’, nickname=‘及时雨’}
04从尾到头打印单链表【百度,要求方式1:反向遍历,方式2:Stack栈】
思路分析:
1.利用栈先进后出的特点,实现逆序打印效果。
栈的基本用法:入栈、出栈
Stack<String> stack = new Stack<>();
//入栈
stack.push("张三");
stack.push("王五");
stack.push("赵六");
//出栈
while (stack.size() > 0){
System.out.println(stack.pop());
}
打印结果:
赵六
王五
张三
实现栈的逆序打印:
//实现链表的逆序打印
public static void reversePrint(HeroNode head){
//判断链表是否为空
if (head.next == null){
return;
}
//创建栈,将各个节点压入栈中
Stack<HeroNode> stack = new Stack<>();
//辅助变量指向节点
HeroNode cur = head.next;
//入栈
while (cur != null) {
stack.push(cur);
//节点后移 下一个节点压入栈
cur = cur.next;
}
//出栈
while (stack.size() > 0){
System.out.println(stack.pop());
}
}
代码测试:
public class SingleLinkedListDemo {
public static void main(String[] args) {
SingleLinkedList singleLinkedList = new SingleLinkedList();
HeroNode hero1 = new HeroNode(1, "宋江", "及时雨");
HeroNode hero2 = new HeroNode(2, "卢俊义", "玉麒麟");
HeroNode hero3 = new HeroNode(3, "吴用", "智多星");
HeroNode hero4 = new HeroNode(4, "林冲", "豹子头");
HeroNode hero5 = new HeroNode(5, "李逵", "黑旋风");
//添加英雄
singleLinkedList.add(hero1);
singleLinkedList.add(hero3);
singleLinkedList.add(hero5);
singleLinkedList.add(hero2);
//循环遍历
System.out.println("单链表的信息");
singleLinkedList.list();
System.out.println("测试逆序打印链表");
reversePrint(singleLinkedList.getHead());
}
}
测试结果:
单链表的信息
HeroNode{no=1, name=‘宋江’, nickname=‘及时雨’}
HeroNode{no=3, name=‘吴用’, nickname=‘智多星’}
HeroNode{no=5, name=‘李逵’, nickname=‘黑旋风’}
HeroNode{no=2, name=‘卢俊义’, nickname=‘玉麒麟’}
测试逆序打印链表
HeroNode{no=2, name=‘卢俊义’, nickname=‘玉麒麟’}
HeroNode{no=5, name=‘李逵’, nickname=‘黑旋风’}
HeroNode{no=3, name=‘吴用’, nickname=‘智多星’}
HeroNode{no=1, name=‘宋江’, nickname=‘及时雨’}
以上就是单链表的一些面试题。方法不是唯一的可以尝试多种方法。