//版本1:恶汉式,直接使用静态属性分配资源,存在资源浪费的问题 class Singleton1{ public static final Singleton1 instance = new Singleton1(); private Singleton1(){} public Singleton1 getInstance(){ return instance; } } //版本2 懒汉式,存在线程安全问题 class Singleton2{ private static Singleton2 instance = null; private Singleton2(){} public Singleton2 getInstance(){ if(instance == null){ instance = new Singleton2(); } return instance; } } //版本3 double check 线程安全 class Singleton3{ private Singleton3(){} private volatile static Singleton3 instance = null; public static Singleton3 getInstance(){ if(instance == null){ synchronized (Singleton3.class){ if(instance == null){ instance = new Singleton3(); } } } return instance; } } //版本4 静态内部类,被调用的时候初始化 class Singleton4{ private Singleton4(){} public static Singleton4 getInstance(){ return InnerSingle.instance; } public static class InnerSingle{ public static final Singleton4 instance = new Singleton4(); } } //版本5 枚举 enum Singleton5{ instance; private String attr; void setAttr(String attr){ this.attr = attr; } String getAttr(){ return this.attr; } }
注:以上只提供复习使用,不提供细节原理。
题3:
/** * 面试题3:数组中重复的数 题目要求: 在一个长度为n的数组中,所有数字的取值范围都在[0,n-1],但 不知道有几个数字重复或重复几次,找出其中任意一个重复的数字。 思路: 1.排序 时间复杂度 O(nlgn) 顺序遍历相邻元素O(n) 2.暴力解决 O(n^2) 3.哈希表 O(1)时间查询哈希表,若存在则直接返回,不存在就添加至哈希表中 4.根据数字特点排序 会改变原数组 5.二路计数,分别计算不同组的元素个数, */ public static void main(String [] args){ int [] data = {2,3,1,0,2,5,3}; //System.out.println(getDuplication1(data)); //System.out.println(getDuplication2(data)); System.out.println(getDuplication3(data)); } //使用hash表 public static int getDuplication1(int [] data){ if(data == null || data.length < 2){ return -1; } int[] hashTable = new int[data.length]; for(int d:data){ if(hashTable[d] >=1){ return d; } else{ hashTable[d] = 1; } } return -1; } //根据数字特点排序 public static int getDuplication2(int [] data){ if(data == null || data.length < 2){ return -1; } //只要数组元素与下标不相等,则到元素值对应的下标比较元素相等,若相等则直接返回元素, //如果不相等,则交换两者 for(int i = 0;i< data.length ;i++){ while(i != data[i]){ if(data[data[i]] == data[i]){ return data[i]; }else{ int temp = data[i]; data[i] = data[temp]; data[temp] = temp; } } } return -1; } //二路计数 public static int getDuplication3(int [] data){ if(data ==null || data.length < 1){ return -1; } int start = 0; int end = data.length - 2; while(start <= end){ int middle = ((end - start)>>1) + start; int count = countRange(data, start ,middle); if(start == end){ if(count > 1){ return start; }else{ return -1; } } if(count > (middle - start + 1)){ end = middle; }else{ start = middle + 1; } } return -1; } public static int countRange(int[] data, int start , int end){ if(data == null || data.length < 1 ){ return -1; } int count = 0; for(int d:data){ if(d >= start && d <= end){ ++count; } } return count; } }
6、反序打印链表
public static class ListNode<T>{ private T val; private ListNode<T> next; public ListNode(T val){ this.val = val; this.next = null; } } public static void main(String [] args){ ListNode<Integer> head = new ListNode<>(1); head.next = new ListNode<>(2); head.next.next = new ListNode<>(3); //reversePrintListNode(head); reversePrintListNodeWithNoRecurisive(head); } //从尾到头打印链表 public static void reversePrintListNode(ListNode<Integer> head){ if(head == null ){ return; } else{ reversePrintListNode(head.next); System.out.println(head.val); } } //从尾到头打印链表使用非递归版 public static void reversePrintListNodeWithNoRecurisive(ListNode<Integer> head){ Stack<Integer> stack = new Stack<>(); while(head!= null){ stack.push(head.val); head = head.next; } while(!stack.isEmpty()){ System.out.println(stack.pop()); } }