java面试算法题(2)
来源:互联网 发布:美工培训班多少钱 编辑:程序博客网 时间:2024/05/16 14:45
引言
本篇博文中核心是对单链表的数据操作,从不同角度分析问题,寻求不同的结果。分享给大家。
题目
存在一个单链表,寻找这个单链表倒数第K的元素。比如{1->2->3->4->5},倒数第2个元素为4。
分析一
最容易想到的是:我们自己先遍历一遍链表,获取链表的总长度为N,那么我们就知道倒数第K的元素位置就是N-K。然后重新遍历该链表,寻找N-K位置的元素就可以了。
实现代码一
package com.brickworkers;/** * * @author Brickworker * Date:2017年6月28日下午2:25:55 * 关于类Example.java的描述:在单链表中寻找倒数第K个元素 * Copyright (c) 2017, brcikworker All Rights Reserved. */public class Example<T> { //定义一个头节点 Node head = null; //定义一个内部类,表示一个链表的节点 class Node{ private T t; Node next; public Node(T t) { this.t = t; } } //链表插入数据 public void insert(T t){ Node node = new Node(t); //如果头结点是空,那就是首次插入 if(head == null){ head = node; }else { //如果头结点不为空,那么寻找最后为空的位置插入 Node p = head; while(p.next!= null){ p = p.next; } p.next = node; } } //展示链表状态 public void print(){ Node p = head; while(p!=null){ System.out.print(p.t + "->"); p = p.next; } System.out.print("null\n"); } //打印倒数第K个元素 //分析一 public void analysis1(int K){ if(K < 1){ throw new IllegalArgumentException("K参数不合法"); } //先遍历一次链表获得总长度 int count = 0; Node p = head; while(p !=null ){ count ++; p = p.next; } //再遍历一遍链表获得对于的值 count = count - K;//把倒数转成顺序遍历的位置 p = head; while(count > 0){ p = p.next; count --; } System.out.println("倒数第" + K +"个元素为:" + p.t); } public static void main(String[] args) { //构建一个链表 Example<Integer> example = new Example<Integer>(); example.insert(1); example.insert(2); example.insert(3); example.insert(4); example.insert(5); //打印链表结构 example.print(); //获取倒数第三个元素 example.analysis1(3); }}////1->2->3->4->5->null//倒数第3个元素为:3
在上面的代码中,构建了一个自定义的单链表结构。这种解决方式是最容易想到,而且代码写起来也非常顺利。
分析二
第二种容易想到的办法就是蛮力法,如果从链表中的某一个节点开始,遍历K个元素到达链表尾部,那么这个开始的节点就是倒数第K个节点。那么实现上来说,我们就需要对每一个节点尝试进行遍历K个元素,查看是否到达链表尾部就可以了。比如开始的节点为C,那么只要保证C.(K-1).next !=null && C.K.next ==null的时候C就是我们要寻找的节点。但是在代码中,我们从头开始遍历,只需要恰好出现最后一个为null的时候就可以确认倒数第K个数了。
实现代码二
//为了节省篇幅,只提供核心代码,其余代码和实现代码一是一样的,只需要把下面代码嵌入使用就可以 public void analysis2(int K){ if(K < 1){ throw new IllegalArgumentException("K参数不合法"); } //从头开始遍历链表 Node p = head; while(getIndex(p, K) != null){ p = p.next; } System.out.println("倒数第" + K +"个元素为:" + p.t); } //获取当前位置后k个数 private Node getIndex(Node n, int k){ while(k > 0){ n = n.next; k --; } return n; }
在上述的代码中,其实时间复杂度比分析一种的还要高,假如存在n个元素,那么最差时间复杂度就是O(kn),效率比较低下,但是可以拓展思维能力。
分析三
还有一个最高效解决这个问题的办法:指针追击。设置两个指针,其中一个指针先行k步,然后两个指针同时向前移动。当先行的指针为null的时候,那么后面这个指针所指向的元素就是倒数第K个元素。
实现代码三
public void analysis3(int K){ if(K < 1){ throw new IllegalArgumentException("K参数不合法"); } //设立两个指针 Node fast = head;//快行K步 Node slow = head; while(K > 0){ //中途出现了null值,一般考虑K值不合法的情况 if(fast == null){ throw new IllegalArgumentException("K参数不合法"); } fast = fast.next; K --; } //两个指针同时向前移动 while(fast != null){ fast = fast.next; slow = slow.next; } System.out.println("倒数第" + K +"个元素为:" + slow.t); }
这种方法效率最高,但是不易想到,但是如果有看过关于类似指针追击,找环这样问题的,应该还是可以运用的上。它只需要遍历一遍链表就可以处理完结果。
总结
在链表中做数据处理的时候,尤其是查找特定条件下的元素,都可以考虑一下多指针是否可以解决问题,往往会有很大收获。
希望对你有所帮助
- java面试算法题(2)
- java面试算法题
- 面试-java算法题
- java面试算法题(1)
- java面试算法题(经典)
- java面试算法题总结
- Java面试常见算法题
- 面试算法题2
- Java面试宝典2010(二。算法题)
- Java面试必问算法题
- 剑指Offer面试算法题Java实现
- 几个面试经典算法题Java解答
- Java面试宝典(5)算法
- java面试算法与设计(基础)
- java面试算法与设计(高级)
- 面试中的算法(java方向)
- java面试算法
- Java面试算法题目
- FIO 测试磁盘iops 以及读写
- 安装docker-compose 并且发布spring boot整合redis做访问计数demo
- 多文件的上传 Android客户端与java服务端
- ros服务学习
- 基于面向对象的轮播图
- java面试算法题(2)
- Syntax error on token "catch", Identifier expected
- 【Python那些事儿】使用箱线图
- IBatis-学习-1
- c#FileStream文件读写.以及filestream,file和FileInfo的区别
- Android Activity启动模式学习
- sql
- 怎么让Windows2012和Windows2008多用户同时远程
- bzoj 3456 城市规划