原题链接:最小子串覆盖
查找一个数组的中位数?
【算法】无序数组中求中位数(https://blog.csdn.net/u010983881/article/details/78160671)
个人直接想法是用栈先进后出的特点,把链表数据读到栈里然后输出。有更好的实现方式吗
a) 假设我们不会给出重复的边在边的列表当中. 无向边 [0, 1] 和 [1, 0] 是同一条边, 因此他们不会同时出现在我们给你的边的列表当中。
样例
1) 给出n = 5 并且 edges = [0, 1], [0, 2], [0, 3], [1, 4], 返回 true.
2) 给出n = 5 并且 edges = [0, 1], [1, 2], [2, 3], [1, 3], [1, 4], 返回 false.
答:http://blog.csdn.net/icoveryou/article/details/5686913
题目一:
提供一个懒汉模式的单实例类实现。
要求:
1.考虑线程安全。
2.提供测试代码,测试线程安全性。
public class Singleton {
public Singleton() {}
/**
* 内部静态类实现单例
*/
private static class SingletonHolder{
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance(){
return SingletonHolder.INSTANCE;
}
public static void main(String[] args) {
//测试代码,验证50个线程去获取单例是不是一个实例
for (int i = 0; i < 50; i++) {
new Thread(() -> System.out.println(Singleton.getInstance().hashCode())).start();
}
}
}
题目二
1.设计含最小函数min()、pop()、push()的栈AntMinStack,存储数据元素为int
2.AntMinStack中数据存储使用Stack结构
要求:
1.AntMinStack实现测试,满足栈特性
2.要求min、push、pop、的时间复杂度都是O(1)
public class AntMinStack {
Stack stack; //存储值
Stack min;//存储最小值
public AntMinStack(){
stack = new Stack<>();
min = new Stack<>();
}
public void push(int data){
stack.push(data);
if (min.isEmpty() || data <= min.peek()){
min.push(data);
}
}
public int pop() throws Exception{
if (stack.isEmpty()){
throw new Exception("EmptyStackException");
}
if (stack.peek() == min.peek()){
min.pop();
}
return stack.pop();
}
public int min() throws Exception{
if (min.isEmpty()){
throw new Exception("EmptyStackException");
}
return min.peek();
}
public static void main(String[] args) throws Exception{
AntMinStack antMinStack = new AntMinStack();
for (int i = 20; i >= 0; i--) {
antMinStack.push(i);
System.out.println("入栈:"+i+",最小值为:"+antMinStack.min());
}
for (int i = 0; i < 19; i++) {
System.out.println("出栈:"+antMinStack.pop()+"最小值为:"+antMinStack.min());
}
}
}
题目三
假设本地有一个文件夹,文件夹下面有若干文件(文件数大于50小于100),文件的存储格式是文本格式(后缀名是.txt),文件的大小每个文件不会超过100k
文件格式如下:
2000102,100,98.32000103,101,73.32000104,102,98.32000105,100,101.32000106,101,45.3……
文件格式说明:文件每行都由三列构成,第一列是一个id,第二列是分组groupId, 第三列是指标quota。
id的数据类型是String, groupId的数据类型String, quota的数据类型float。
功能要求:1.把所有文件里面的内容按照分组进行排序,输出所有文件按照分组升序排序之后,每个分组下面的最小指标值。比如上面的数据输出结果为:100,2000102,98.3101,2000106,45.3102,2000104,98.3
非功能要求:
1.文件读取要有线程池来执行,线程池的大小固定为10,文件内容需要存储到指定的内容数据结构当中
2.查找要求有独立线程来执行,直接消费读取线程池产生的内存数据结构。
3.文件读取和排序要求并发作业,文件读取只要产生了数据,就可以把数据交给排序线程进行消费,计算最小值。
代码要求
1.重上面的要求语意里面抽象出合适的设计模式。
2.需要考虑多线程的并发控制,同步机制。
3.代码实现只能用JDK1.6或者1.8自带的工具类
/**
*
* 生产者线程
* Author: Administrator Date: 2018年8月28日
*
*/
public class Producer implements Runnable{
private LinkedBlockingQueue queue;
private File file;
private CountDownLatch countDownLatch;
public Producer(LinkedBlockingQueue queue,File file,CountDownLatch countDownLatch) {
this.queue = queue;
this.file = file;
this.countDownLatch = countDownLatch;
}
@Override
public void run() {
try {
InputStreamReader read = new InputStreamReader(new FileInputStream(file));
BufferedReader br=new BufferedReader(read);
String line="";
String[] arrs=null;
while ((line=br.readLine())!=null) {
if (line.equals("")) {
continue;
}
arrs=line.split(",");
DataItem dataItem = new DataItem();
dataItem.setId(arrs[0]);
dataItem.setGroupId(arrs[1]);
dataItem.setQuota(new Float(arrs[2]));
queue.add(dataItem);
}
br.close();
read.close();
countDownLatch.countDown();
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
*
* 消费者线程
* Author: Administrator Date: 2018年8月28日
*
*/
public class Consumer implements Runnable{
private LinkedBlockingQueue queue;
private TreeMap treeMap;
private CountDownLatch countDownLatch;
public Consumer(LinkedBlockingQueue queue,TreeMap treeMap,CountDownLatch countDownLatch) {
this.queue = queue;
this.treeMap = treeMap;
this.countDownLatch = countDownLatch;
}
@Override
public void run() {
try {
while(true){
if (!queue.isEmpty()) {
DataItem dataItem = queue.take();
DataItem mydataItem = treeMap.get(dataItem.getGroupId());
if (mydataItem == null) {
treeMap.put(dataItem.getGroupId(), dataItem);
}else{
if (dataItem.getQuota() < mydataItem.getQuota()) {
treeMap.put(dataItem.getGroupId(), dataItem);
}
}
}else{
if(countDownLatch.getCount() <= 1){
countDownLatch.countDown();
break;
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
*
* 数据仓库
* Author: Administrator Date: 2018年8月29日
*
*/
public class DataWareHouse {
private static final int THREAD_POOL_SIZE = 10;
private LinkedBlockingQueue queue;//缓存生产者线程从文件读取的数据
private TreeMap treeMap;//存储消费者线程处理后的数据(排序、获取同组指标最小的数据)
private ExecutorService threadPool;//线程池
public DataWareHouse() {
queue = new LinkedBlockingQueue<>();
treeMap = new TreeMap<>(new Comparator() {
@Override
public int compare(String o1, String o2) {
return Long.valueOf(o1).compareTo(Long.valueOf(o2));
}
});
threadPool = Executors.newFixedThreadPool(THREAD_POOL_SIZE);
}
public LinkedBlockingQueue getQueue() {
return queue;
}
public void setQueue(LinkedBlockingQueue queue) {
this.queue = queue;
}
public TreeMap getTreeMap() {
return treeMap;
}
public void setTreeMap(TreeMap treeMap) {
this.treeMap = treeMap;
}
public ExecutorService getThreadPool() {
return threadPool;
}
public void setThreadPool(ExecutorService threadPool) {
this.threadPool = threadPool;
}
}
/**
*
*
* Author: Administrator Date: 2018年8月28日
*
*/
public class DataItem {
/**
* id
*/
private String id;
/**
* 分组
*/
private String groupId;
/**
* 指标
*/
private Float quota;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getGroupId() {
return groupId;
}
public void setGroupId(String groupId) {
this.groupId = groupId;
}
public Float getQuota() {
return quota;
}
public void setQuota(Float quota) {
this.quota = quota;
}
public class Main {
public static void main(String[] args) {
String dirPath = "src/main/resources/files";
File dirFile = new File(dirPath);
File[] files = dirFile.listFiles();
DataWareHouse dataWareHouse = new DataWareHouse();
CountDownLatch countDownLatch = new CountDownLatch(files.length + 1);
for(File file : files){
Producer producer = new Producer(dataWareHouse.getQueue(), file,countDownLatch);
//生产者线程使用线程池
dataWareHouse.getThreadPool().execute(producer);
}
Consumer consumer = new Consumer(dataWareHouse.getQueue(), dataWareHouse.getTreeMap(),countDownLatch);
//一个消费者线程消费
new Thread(consumer).start();
try {
//生产者线程和消费者线程执行完成,关闭线程池,输出结果
countDownLatch.await();
dataWareHouse.getThreadPool().shutdownNow();
} catch (Exception e) {
e.printStackTrace();
}
Iterator> it = dataWareHouse.getTreeMap().entrySet().iterator();
while(it.hasNext()) {
Entry entry = it.next();
DataItem dataItem = entry.getValue();
System.out.println(dataItem.getGroupId() + "," + dataItem.getId()+","+dataItem.getQuota());
}
}
/**
* 创建测试数据
* @author jiangpan
* @title CreateDataTest.java
* @date 2018年8月29日
*
*/
public class CreateDataTest {
public static void main(String[] args) throws IOException {
String path = "src/main/resources/files/";
for (int i = 1; i < 100; i++) {
File file = new File(path+i+".txt");
if(!file.exists()){
file.createNewFile();
}
FileWriter fileWriter = new FileWriter(file);
BufferedWriter br = new BufferedWriter(fileWriter);
for (int j = 0; j < 5000; j++) {
br.write(getRandomData());
br.newLine();
}
br.close();
fileWriter.close();
}
System.out.println("success");
}
private static String getRandomData(){
Integer id = (int)(Math.random() * 1000000) + 1000000;
Integer groupId = (int)(Math.random() * 1000) + 100;
Float quota = (int)(Math.random() * 1000)/10.0f+60;
return id+","+groupId+","+quota;
}
排序算法:了解哪些排序算法,讲讲复杂度
手撕归并排序
排序算法
面试中的排序算法总结(https://www.cnblogs.com/wxisme/p/5243631.html)
冒泡排序、选择排序、插入排序、快速排序、堆排序、希尔排序、归并排序、计数排序、桶排序、基数排序、
算法 最快时间复杂度 平均时间复杂度 最坏时间复杂度 空间复杂度 是否稳定
冒泡排序 Ω(n) Θ(n2) O(n2) O(1) 稳定
插入排序 Ω(n) Θ(n2) O(n2) O(1) 稳定
希尔排序 Ω(nlogn) Θ(n(log(n))2) O(n(log(n))2) O(1) 不稳定
选择排序 Ω(n2) Θ(n2) O(n2) O(1) 不稳定
堆排序 Ω(nlogn) Θ(nlogn) O(nlogn) O(1) 不稳定
归并排序 Ω(nlogn) Θ(nlogn) O(nlogn) O(n) 稳定
快速排序 Ω(nlogn) Θ(nlogn) O(nlogn) O(logn) 不稳定
基数排序 Ω(n+b) Θ(n+b) O(n+b) O(n+k) 稳定
O表示上界(小于等于)Ω表示下界(大于等于)Θ表示即是上界也是下界(等于)