Java数据结构与算法-单链表 新浪,腾讯面试题详解

放肆的年华 提交于 2020-03-12 17:24:52

单链表常见的几个面试题

  • 新浪,腾讯内部面试题目
  • 题目分析
  • 代码实现
  • 测试用例

一,面试题目

  1. 统计链表中有效节点的个数(不含头结点)【新浪】
  2. 获取链表中倒数第K个元素【新浪】
  3. 单向链表的逆转【腾讯】

二,题目分析

  1. 第一题:我们可以获取链表的头结点后,然后进行遍历,设置一个变量进行计数,注意不要算上头结点
  2. 第二题:我们可以在第一题的基础上,在获取到了链表的长度后,只需要考虑倒数第K个节点是从前面开始第几个节点,我们就循环几次不就可以了?注意如果你的下标从0开始循环那就size - k就可以了,如果你是从1开始的那么就size-k+1就可以了。
  3. 第三题:我们需要创建一个新的头结点,然后把原来的那个节点从前往后依次放到新节点的后面,注意是newHeadNode.next始终等于新加入的那个元素;核心代码就是:oldNode.next = newHeadNode.next;newHeadNode.next = oldNode;就是这样移动,最后在把新的节点后的元素指向原来头结点:oldHeadNode = newHeadNode;
    图解如下:
    在这里插入图片描述
    三,代码实现

第一题

	//统计出有效的节点个数,不含头结点。
	public static int getLength(HeroNode headHeroNode) {
		int count = 0;
		if (headHeroNode.next == null) {
			return 0;
		}
		HeroNode temp = headHeroNode.next;//不统计头结点,有两种写法任选其一。
		while (temp != null) {
			count++;
			temp = temp.next;
		}
		return count;
	}

第二题

//查找单链表中的倒数第k个结点【新浪面试题】
	public static void find(HeroNode head,int index){
			
		if (head.next == null) {
			System.out.println("英雄榜为空!");
			return ;
		}
		HeroNode temp = head;
		int size = getLength(head);
		if (index >size||index<0) {
			System.out.println("输入的K不合法!");
		}else {
			for (int i = 1; i <= size-index+1; i++) {
				temp = temp.next;
			}
			System.out.println("倒数第K个元素是:"+temp);
			
		}
			
	}

第三题:

//链表逆转【腾讯面试题目】
	public static void reverse(HeroNode head) {
		
		if (head.next == null || head.next.next ==null) {
			System.out.println("链表未发生变化!");
			return;
		}
		
		HeroNode current = head.next;
		HeroNode newheadHeroNode =new HeroNode(0,"","");
		HeroNode currentnext = null;
		
		while (current != null) {
			currentnext = current.next;
			current.next = newheadHeroNode.next;
			newheadHeroNode.next = current;
			current = currentnext;
		}
		head.next = newheadHeroNode.next;
		System.out.println("链表已经逆转");
		
	}

完整的测试代码如下:

package com.atxiaopeng.linkedlist;

import java.util.Scanner;

public class SingleLinkedListDemo {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		// 1,创建英雄榜
		SingleLinkedlist s = new SingleLinkedlist();
		// HeroNode h1 = new HeroNode(1, "阿珂", "节奏热浪");
		// HeroNode h2 = new HeroNode(2, "猴子", "大圣娶亲");
		// HeroNode h3 = new HeroNode(3, "李白", "凤 求 凰");
		// HeroNode h4 = new HeroNode(4, "露娜", "紫霞仙子");
		boolean b = true;
		while (b) {

			System.out.println("==========王者英雄榜==========");
			System.out.println("      1,创建英雄并进榜(无序) ");
			System.out.println("      2,创建英雄并进榜(有序)");
			System.out.println("      3,修改英雄属性                       ");
			System.out.println("      4,英雄榜删除英雄        ");
			System.out.println("      5,显示当前英雄榜    ");
			System.out.println("      6,英雄总榜人数        ");
			System.out.println("      7,查找倒数第K个英雄    ");
			System.out.println("      8,英雄逆序排列      ");
			System.out.println("      9,退出程序      ");
			System.out.println("===========================");
			System.out.print("输入操作的选项:  ");

			int key = new Scanner(System.in).nextInt();
			switch (key) {
			case 1:
				s.createHero1();
				break;

			case 2:
				s.createHero2();
				break;

			case 3:
				s.update();
				break;
			case 4:
				s.delete();
				break;
			case 5:
				s.show();
				break;
			case 6:
				System.out.println(getLength(s.getHeadHeroNode()));
				break;
			case 7:
				find(s.getHeadHeroNode(), 1);
				break;
			case 8:
				reverse(s.getHeadHeroNode());
				break;
			case 9:
				b = false;
				System.out.println("程序成功退出!");
				break;

			default:
				break;
			}

		}

	}
	//统计出有效的节点个数,不含头结点。
	public static int getLength(HeroNode headHeroNode) {
		int count = 0;
		if (headHeroNode.next == null) {
			return 0;
		}
		HeroNode temp = headHeroNode.next;//不统计头结点,有两种写法任选其一。
		while (temp != null) {
			count++;
			temp = temp.next;
		}
		return count;
	}
	//查找单链表中的倒数第k个结点【新浪面试题】
	public static void find(HeroNode head,int index){
			
		if (head.next == null) {
			System.out.println("英雄榜为空!");
			return ;
		}
		HeroNode temp = head;
		int size = getLength(head);
		if (index >size||index<0) {
			System.out.println("输入的K不合法!");
		}else {
			for (int i = 1; i <= size-index+1; i++) {
				temp = temp.next;
			}
			System.out.println("倒数第K个元素是:"+temp);
			
		}
			
	}
	
	//链表逆转【腾讯面试题目】
	public static void reverse(HeroNode head) {
		
		if (head.next == null || head.next.next ==null) {
			System.out.println("链表未发生变化!");
			return;
		}
		
		HeroNode current = head.next;
		HeroNode newheadHeroNode =new HeroNode(0,"","");
		HeroNode currentnext = null;
		
		while (current != null) {
			currentnext = current.next;
			current.next = newheadHeroNode.next;
			newheadHeroNode.next = current;
			current = currentnext;
		}
		head.next = newheadHeroNode.next;
		System.out.println("链表已经逆转");
		
	}
	
}

	
class SingleLinkedlist {

	// 1,创建头结点,不存放数据,不让随便动
	private HeroNode headHeroNode = new HeroNode(0, "", "");
	
	public HeroNode getHeadHeroNode() {
		return headHeroNode;
	}

	boolean flag = false;// 判断标志,例如:判断为空的标志等
	// 创建英雄并无序插入

	public void createHero1() {
		System.out.print("输入你要加入英雄的排名:");
		int newNu = new Scanner(System.in).nextInt();
		System.out.print("输入你要加入英雄的名字:");
		String newName = new Scanner(System.in).next();
		System.out.print("输入你要加入的英雄的常用皮肤:");
		String newSkin = new Scanner(System.in).next();
		add(new HeroNode(newNu, newName, newSkin));
	}

	// 创建英雄并有序插入
	public void createHero2() {
		System.out.print("输入你要加入英雄的排名:");
		int newNu = new Scanner(System.in).nextInt();
		System.out.print("输入你要加入英雄的名字:");
		String newName = new Scanner(System.in).next();
		System.out.print("输入你要加入的英雄的常用皮肤:");
		String newSkin = new Scanner(System.in).next();
		addByordering(new HeroNode(newNu, newName, newSkin));
	}

	// 2,无序插入
	public void add(HeroNode heroNode) {

		HeroNode temp = headHeroNode;
		while (true) {
			if (temp.next == null) {
				break;
			}
			if (temp.next.nu == heroNode.nu) {
				flag = true;
				break;
			}
			temp = temp.next;
		}
		if (flag) {
			System.out.println("排名 : " + heroNode.nu + " 英雄之前已经加入,不能再次加入!");
		} else {
			heroNode.next = temp.next;
			temp.next = heroNode;
			System.out.println(heroNode.name + " 成功加入王者英雄榜!(无序)");
		}
		flag = false;

	}

	// 3,有序插入
	public void addByordering(HeroNode heroNode) {

		HeroNode temp = headHeroNode;
		while (true) {

			if (temp.next == null) {
				break;
			}
			if (temp.next.nu > heroNode.nu) {
				break;
			} else if (temp.next.nu == heroNode.nu) {
				flag = true;
				break;
			}
			temp = temp.next;
		}
		if (flag) {
			System.out.println("排名 : " + heroNode.nu + " 英雄之前已经加入,不能再次加入!");
		} else {
			heroNode.next = temp.next;
			temp.next = heroNode;
			System.out.println(heroNode.name + " 成功加入王者英雄榜!(有序)");
		}
		flag = false;
	}

	// 删除英雄
	public void delete() {

		HeroNode temp = headHeroNode;
		HeroNode random;

		if (temp.next == null) {
			System.out.println("英雄榜为空,无法删除!!!");
			return; // 直接返回,不再继续往下运行
		}

		System.out.print("输入要删除英雄的名字:");
		Scanner input = new Scanner(System.in);
		String s1 = input.next();
		while (true) {
			if (temp.next == null) {
				flag = true;
				break;
			} else if (temp.next.name.equals(s1)) {
				break;
			}
			temp = temp.next;
		}
		if (flag) {
			System.out.println("英雄榜中不存在该英雄,无法删除!!!");
		} else {
			random = temp.next;
			temp.next = random.next;
			System.out.println(random.name + " 英雄删除成功!");
		}
		flag = false;
	}

	// 修改英雄属性
	public void update() {

		HeroNode temp = headHeroNode;
		if (temp.next == null) {
			System.out.println("英雄榜为空,无法修改!");
			return;
		}

		System.out.print("输入你要修改的英雄的名字:");
		String name = new Scanner(System.in).next();
		while (true) {
			if (temp.next == null) {
				flag = true;
				break;
			} else if (temp.next.name.equals(name)) {
				break;
			}
			temp = temp.next;
		}
		if (flag) {
			System.out.println("英雄榜中不存在该英雄,无法修改!!!");
		} else {
			System.out.print("输入你要修改英雄的名字:");
			String newName = new Scanner(System.in).next();
			System.out.print("输入你要修改的英雄的常用皮肤:");
			String newSkin = new Scanner(System.in).next();
			temp.next.name = newName;
			temp.next.skin = newSkin;
			System.out.println("===英雄榜已更新!===");
		}
		flag = false;

	}

	// 显示英雄榜
	public void show() {

		HeroNode temp = headHeroNode;

		if (temp.next == null) {
			System.out.println("王者英雄榜尚未有英雄加入!");
			return;
		}
		while (true) {
			if (temp.next == null) {
				break;
			}

			temp = temp.next;
			System.out.println(temp + " ");
		}

	}

}

class HeroNode {

	public int nu;
	public String name;
	public String skin;
	public HeroNode next;

	public HeroNode(int n, String name, String skin) {
		this.nu = n;
		this.name = name;
		this.skin = skin;
	}

	@Override
	public String toString() {
		return "王者英雄榜 :[排名=" + nu + ", 名字=" + name + ", 皮肤=" + skin + "]";
	}

}

欢迎指正,共同学习!

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!