现在也一月份了,春招的话金三银四,要好好把握,想起我去年一月份的时候还在忙着看面试总结,这是我之前面试总结的知识点,一部分是网上down来的,一部分是搜集的面试问题,应该是很全面了,问来问去基础也就那些,无论是BAT等一线大厂或者其他不同的企业这些面试题目足够了,再也有一些推荐的书单这个大家可以在网上找然后自行下载和也附上我的一些资料,具体的学习路线不用多说,自行Baidu即可,弄懂了这些面试常见问题,基础的方面算是解决了,剩下的项目经验还要注重平时积累,切忌临时抱佛脚,很快就会露馅的。

网站推荐

http://gityuan.com/2016/01/09/java-memory/内存模型 http://www.guokr.com/post/114121/ Https握手 http://blog.csdn.net/laner0515/article/details/27692673/核心工作原理 http://www.cnblogs.com/fanzhidongyzby/p/4098546.html IO http://blog.csdn.net/sszgg2006/article/details/38664789 IO http://blog.csdn.net/forfuture3513/article/details/52445213 IO http://www.blogjava.net/bolo/archive/2015/01/20/422296.html 并发模型 http://blog.csdn.net/qq396229783/article/details/19924393 String http://jingyan.baidu.com/article/acf728fd2182e7f8e510a32e.html 中文编码问题 http://www.cnblogs.com/200911/p/3965108.html 内存溢出解决方案 https://www.nowcoder.com/discuss/5683 spring问题 http://blog.csdn.net/u010425776/article/details/55006347 计算机网络 http://blog.csdn.net/hguisu/article/details/7445768/ Socket http://www.jb51.net/article/19024.htm SQL优化 http://www.cnblogs.com/coder2012/p/5309197.html 索引 http://www.360doc.com/content/14/0903/10/15077656_406704297.shtml redis设计与实现 http://blog.csdn.net/sinat_35512245/article/details/59056120 面试题总结网址

书单推荐

PS:这些书都是一些业内有名的书网上链接也比较多就不一一列举了同一种类型的大家可以读一两本对照即可,这些我都粗略读过,都是不错的书籍,值得推荐,web方向尤其是一些关于大型网站技术架构方面一定要了解一下,可以在项目面吹水一下,感觉也是不错的

面试题汇总

  1. 九种基本数据类型的大小,以及他们的封装类。
  2. Switch能否用string做参数?
  3. equals与==的区别。
  4. Object有哪些公用方法?
  5. Java的四种引用,强弱软虚,用到的场景
  6. Hashcode的作用。
  7. ArrayList、LinkedList、Vector的区别。
  8. String、StringBuffer与StringBuilder的区别。
  9. Map、Set、List、Queue、Stack的特点与用法。
  10. HashMap和HashTable的区别。
  11. HashMap和ConcurrentHashMap的区别,HashMap的底层源码。
  12. TreeMap、HashMap、LindedHashMap的区别。
  13. Collection包结构,与Collections的区别。
  14. try catch finally,try里有return,finally还执行么?
  15. Excption与Error包结构。OOM你遇到过哪些情况,SOF你遇到过哪些情况。
  16. Java面向对象的三个特征与含义。
  17. Override和Overload的含义去区别。
  18. Interface与abstract类的区别。
  19. Static class 与non static class的区别。
  20. java多态的实现原理。
  21. 实现多线程的两种方法:Thread与Runable。
  22. 线程同步的方法:sychronized、lock、reentrantLock等。
  23. 锁的等级:方法锁、对象锁、类锁。
  24. 写出生产者消费者模式。
  25. ThreadLocal的设计理念与作用。
  26. ThreadPool用法与优势。
  27. Concurrent包里的其他东西:ArrayBlockingQueue、CountDownLatch等等。
  28. wait()和sleep()的区别。
  29. foreach与正常for循环效率对比。
  30. Java IO与NIO。
  31. 反射的作用于原理。
  32. 泛型常用特点,List能否转为List。
  33. 解析XML的几种方式的原理与特点:DOM、SAX、PULL。
  34. Java与C++对比。
  35. Java1.7与1.8新特性。
  36. 设计模式:单例、工厂、适配器、责任链、观察者等等。
  37. JNI的使用。 JVM
  38. 内存模型以及分区,需要详细到每个区放什么。
  39. 堆里面的分区:Eden,survival from to,老年代,各自的特点。
  40. 对象创建方法,对象的内存分配,对象的访问定位。
  41. GC的两种判定方法:引用计数与引用链。
  42. GC的三种收集方法:标记清除、标记整理、复制算法的原理与特点,分别用在什么地方,如果让你优化收集方法,有什么思路?
  43. GC收集器有哪些?CMS收集器与G1收集器的特点。
  44. Minor GC与Full GC分别在什么时候发生?
  45. 几种常用的内存调试工具:jmap、jstack、jconsole。
  46. 类加载的五个过程:加载、验证、准备、解析、初始化。
  47. 双亲委派模型:Bootstrap ClassLoader、Extension ClassLoader、ApplicationClassLoader。
  48. 分派:静态分派与动态分派。 操作系统
  49. 进程和线程的区别。
  50. 死锁的必要条件,怎么处理死锁。
  51. Window内存管理方式:段存储,页存储,段页存储。
  52. 进程的几种状态。
  53. IPC几种通信方式。
  54. 什么是虚拟内存。
  55. 虚拟地址、逻辑地址、线性地址、物理地址的区别。 TCP/IP
  56. OSI与TCP/IP各层的结构与功能,都有哪些协议。
  57. TCP与UDP的区别。
  58. TCP报文结构。 4.TCP的三次握手与四次挥手过程,各个状态名称与含义,TIMEWAIT的作用。
  59. TCP拥塞控制
  60. TCP滑动窗口与回退N针协议。
  61. Http的报文结构。
  62. Http的状态码含义。
  63. Http request的几种类型。
  64. Http1.1和Http1.0的区别
  65. Http怎么处理长连接。
  66. Cookie与Session的作用于原理。
  67. 电脑上访问一个网页,整个过程是怎么样的:DNS、HTTP、TCP、OSPF、IP、ARP。
  68. Ping的整个过程。ICMP报文是什么。
  69. C/S模式下使用socket通信,几个关键函数。
  70. IP地址分类。
  71. 路由器与交换机区别。 数据结构与算法
  72. 链表与数组。
  73. 队列和栈,出栈与入栈。
  74. 链表的删除、插入、反向。
  75. 字符串操作。
  76. Hash表的hash函数,冲突解决方法有哪些。
  77. 各种排序:冒泡、选择、插入、希尔、归并、快排、堆排、桶排、基数的原理、平均时间复杂度、最坏时间复杂度、空间复杂度、是否稳定。
  78. 快排的partition函数与归并的Merge函数。
  79. 对冒泡与快排的改进。
  80. 二分查找,与变种二分查找。
  81. 二叉树、B+树、AVL树、红黑树、哈夫曼树。
  82. 二叉树的前中后续遍历:递归与非递归写法,层序遍历算法。
  83. 图的BFS与DFS算法,最小生成树prim算法与最短路径Dijkstra算法。
  84. KMP算法。
  85. 排列组合问题。
  86. 动态规划、贪心算法、分治算法。(一般不会问到)
  87. 大数据处理:类似10亿条数据找出最大的1000个数.........等等 面向对象和面向过程的区别 面试问题(来自BAT等企业):

IO模型有哪些? 进程线程的区别 不同操作系统实现进程有什么区别 gc算法,回收器有哪些 ACID,事务隔离机制 syn在方法上和代码块有什么不同 memcached和其他nosql的区别 解释mvc threadlocal解释 volatile的作用 堆和栈的区别和联系 tcp和udp的不同之处 tcp如何保证可靠的 数组和链表的区别 排序算法应用场景 lucene全文检索原理

动态规划 spring事务 内存线程隔离 sleep()wait 三次握手两次回收 S1和S2 RuntimeException HashMap中hash future Callable clone 负载因子 二叉树遍历 vector 回溯法 B-Tree 与B+Tree struts和spring HttpServlet容器响应Web客户请求流程如下: 1)Web客户向Servlet容器发出Http请求; 2)Servlet容器解析Web客户的Http请求; 3)Servlet容器创建一个HttpRequest对象,在这个对象中封装Http请求信息; 4)Servlet容器创建一个HttpResponse对象; 5)Servlet容器调用HttpServlet的service方法,这个方法中会根据request的Method来判断具体是执行doGet还是doPost,把HttpRequest和HttpResponse对象作为service方法的参数传给HttpServlet对象; 6)HttpServlet调用HttpRequest的有关方法,获取HTTP请求信息; 7)HttpServlet调用HttpResponse的有关方法,生成响应数据; 8)Servlet容器把HttpServlet的响应结果传给Web客户。

doGet() 或 doPost() 是创建HttpServlet时需要覆盖的方法. java.util.concourrent join 链表相交 判断回文字串 spring和struts 词频统计

集合类以及集合框架;HashMap与HashTable实现原理,线程安全性,hash冲突及处理算法;ConcurrentHashMap

进程和线程的区别;多线程与线程池

数据一致性如何保证;Synchronized关键字,类锁,方法锁,重入锁

同步的方法;多进程开发以及多进程应用场景

服务器只提供数据接收接口,在多线程或多进程条件下,如何保证数据的有序到达

ThreadLocal原理,实现及如何保证Local属性

String StringBuilder StringBuffer对比

接口与回调;回调的原理;写一个回调demo;

泛型原理,举例说明;解析与分派

抽象类与接口的区别;应用场景;抽象类是否可以没有方法和属性

静态属性和静态方法是否可以被继承?是否可以被重写?原因

修改对象A的equals方法的签名,那么使用HashMap存放这个对象实例的时候,会调用哪个equals方法

数据结构与算法

堆和栈在内存中的区别是什么(数据结构方面以及实际实现方面)

最快的排序算法是哪个?给阿里2万多名员工按年龄排序应该选择哪个算法?堆和树的区别;写出快排代码;链表逆序代码

求1000以内的水仙花数以及40亿以内的水仙花数

子串包含问题(KMP 算法)写代码实现

万亿级别的两个URL文件A和B,如何求出A和B的差集C,(Bit映射->hash分组->多文件读写效率->磁盘寻址以及应用层面对寻址的优化)

写出你所知道的排序算法及时空复杂度,稳定性

百度POI中如何试下查找最近的商家功能(坐标镜像+R树) 死锁的四个必要条件

常见编码方式;utf-8编码中的中文占几个字节;int型几个字节

实现一个Json解析器(可以通过正则提高速度)

MVC MVP MVVM; 常见的设计模式;写出观察者模式的代码

TCP的3次握手和四次挥手;TCP与UDP的区别

HTTP协议;HTTP1.0与2.0的区别;HTTP报文结构

手写代码

两个数加起来合为s 输入一个递增排序的数组和一个数字S,在数组中查找两个数,使得他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的。 import java.util.ArrayList; public class Solution { public ArrayList FindNumbersWithSum(int [] array,int sum) { ArrayList result=new ArrayList(); if(array==null||array.length==0){ return result; } int i=0; int j=array.length-1;

    while(i!=j){if(array[i]+array[j]==sum){result.add(array[i]);result.add(array[j]);return result;}else if(array[i]+array[j]>sum){j--; }else{i++;  }}return result;
}
复制代码

}

3.链表中环的入口结点 public class Solution {

public ListNode EntryNodeOfLoop(ListNode pHead)
{ListNode slow=pHead;ListNode fast=pHead;while(fast.next!=null&&slow.next!=null){fast=fast.next.next;slow=slow.next;if(slow==fast){fast=pHead;while(fast!=slow){fast=fast.next;slow=slow.next;}if(slow==fast){return slow;}}}return null;
}
复制代码

}

4.全排列 public ArrayList permutation(String str){ char[] chars=str.toCharArray(); char[] arrs=new char[chars.length]; int []book=new int[chars.length];

dfs(strs,0);

}

peivate ArrayList dfs(char[] strs,step){

if(step==strs.length){ String str=""; for(int i=0;i<arrs.length;i++){

      str=str+arrs[i];
复制代码

} return str; } for(int i=0;i<strs.length;i++){ if(book[i]==0){ arrs[step]=strs[i]; book[i]=1;

dfs(strs,step+1);

book[i]=0; }

} }

import java.util.*;

public class Solution { private char [] seqs; private Integer [] book; //用于结果去重 private HashSet result = new HashSet(); /** * 输入一个字符串,按字典序打印出该字符串中字符的所有排列。 * 例如输入字符串abc,则打印出由字符a,b,c * 所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。 结果请按字母顺序输出。 * 输入一个字符串,长度不超过9(可能有字符重复),字符只包括大小写字母。 * @param str * @return */ public ArrayList Permutation(String str) { ArrayList arrange = new ArrayList(); if(str == null || str.isEmpty()) return arrange; char[] strs = str.toCharArray(); seqs = new char[strs.length]; book = new Integer[strs.length]; for (int i = 0; i < book.length; i++) { book[i] = 0; } dfs(strs, 0); arrange.addAll(result); Collections.sort(arrange); return arrange; }

/*** 深度遍历法*/
private void dfs(char[] arrs, int step){//走完所有可能 记录排列if(arrs.length == step){String str = "";for (int i = 0; i < seqs.length; i++) {str += seqs[i];}result.add(str);return; //返回上一步}//遍历整个序列,尝试每一种可能for (int i = 0; i < arrs.length; i++) {//是否走过if(book[i] == 0){seqs[step] = arrs[i];book[i] = 1;//下一步dfs(arrs, step + 1);//走完最后一步 后退一步book[i] = 0;}}
}
复制代码

}

回溯法 import java.util.*; public class Solution { public ArrayList Permutation(String str) { ArrayList re = new ArrayList(); if (str == null || str.length() == 0) { return re; } HashSet set = new HashSet(); fun(set, str.toCharArray(), 0); re.addAll(set); Collections.sort(re); return re; } void fun(HashSet re, char[] str, int k) { if (k == str.length) { re.add(new String(str)); return; } for (int i = k; i < str.length; i++) { swap(str, i, k); fun(re, str, k + 1); swap(str, i, k); } } void swap(char[] str, int i, int j) { if (i != j) { char t = str[i]; str[i] = str[j]; str[j] = t; } } }

5.二叉树层次遍历 import java.util.; / public class TreeNode { int val = 0; TreeNode left = null; TreeNode right = null;

public TreeNode(int val) {this.val = val;}
复制代码

} */

public class Solution { public ArrayList PrintFromTopToBottom(TreeNode root) { ArrayList level=new ArrayList();

    if(root==null){return level;}Queue <TreeNode> bfs=new LinkedList<TreeNode>();bfs.offer(root);while(!bfs.isEmpty()){TreeNode r=bfs.poll();level.add(r.val);if(r.left!=null){bfs.offer(r.left);}if(r.right!=null){bfs.offer(r.right);}}return level;
}
复制代码

}

6.用两个栈实现队列 public class Queue { private Stack stack1; private Stack stack2;

public Queue() {
复制代码

stack1=new Stack(); stack2=new Stack(); }

public void Stack1toStack2(){while (! stack1.empty()) {
复制代码

stack2.push(stack1.pop()); } } public void push(int element) { stack1.push(element);

}public int pop() {if(stack2.size()==0){Stack1toStack2(); }return stack2.pop();
}public int top() {if(stack2.size()==0){Stack1toStack2(); }return stack2.peek();
}
复制代码

}

7.顺时针打印矩阵 layer=(Math.min(m,n)-1)/2+1;

for(int i=0;i<layer;i++){ for(k=i;k<-i;k++)从左到右 for(j=i;j<n-i;j++ )从右上到右下 for(k=m-i-2;k>=i&&(n-i-1!=i);k--) for(j=n-i-2;(j>=i)&&(m-i-1!=i);j--) }

import java.util.ArrayList; public class Solution { public ArrayList printMatrix(int [][] array) { ArrayList result = new ArrayList (); if(array.length==0) return result; int n = array.length,m = array[0].length; if(m==0) return result; int layers = (Math.min(n,m)-1)/2+1;//这个是层数 for(int i=0;i<layers;i++){ for(int k = i;k<m-i;k++) result.add(array[i][k]);//左至右 for(int j=i+1;j<n-i;j++) result.add(array[j][m-i-1]);//右上至右下 for(int k=m-i-2;(k>=i)&&(n-i-1!=i);k--) result.add(array[n-i-1][k]);//右至左 for(int j=n-i-2;(j>i)&&(m-i-1!=i);j--) result.add(array[j][i]);//左下至左上 } return result;

}
复制代码

}

8.镜面二叉树 public class Solution { public void Mirror(TreeNode root) {

    if(root!=null){ TreeNode temp=root.right;root.right=root.left;root.left=temp;Mirror(root.left);Mirror(root.right);}
复制代码

} }

9.背包问题 本题是典型的01背包问题,每种类型的物品最多只能选择一件。参考前文 Knapsack 中总结的解法,这个题中可以将背包的 size 理解为传统背包中的重量; 题目问的是能达到的最大 size, 故可将每个背包的 size 类比为传统背包中的价值。 考虑到数组索引从0开始,故定义状态bp[i + 1][j]为前 i 个物品中选出重量不超过j时总价值的最大值。 状态转移方程则为分A[i] > j 与否两种情况考虑。初始化均为0,相当于没有放任何物品。 Java

public class Solution { /** * @param m: An integer m denotes the size of a backpack * @param A: Given n items with size A[i] * @return: The maximum size */ public int backPack(int m, int[] A) { if (A == null || A.length == 0) return 0;

    final int M = m;final int N = A.length;int[][] bp = new int[N + 1][M + 1];for (int i = 0; i < N; i++) {for (int j = 0; j <= M; j++) {if (A[i] > j) {bp[i + 1][j] = bp[i][j];} else {bp[i + 1][j] = Math.max(bp[i][j], bp[i][j - A[i]] + A[i]);}}}return bp[N][M];
}
复制代码

}

10.堆排序 package edu.princeton.cs.algs4;

/**

  • The {@code Heap} class provides a static methods for heapsorting

  • an array.

  • For additional documentation, see Section 2.4 of

  • Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

  • @author Robert Sedgewick

  • @author Kevin Wayne */ public class Heap {

    // This class should not be instantiated. private Heap() { }

    /**

    • Rearranges the array in ascending order, using the natural order.
    • @param pq the array to be sorted */ public static void sort(Comparable[] pq) { int n = pq.length; for (int k = n/2; k >= 1; k--) sink(pq, k, n); while (n > 1) { exch(pq, 1, n--); sink(pq, 1, n); } }

/*************************************************************************** * Helper functions to restore the heap invariant. ***************************************************************************/

private static void sink(Comparable[] pq, int k, int n) {while (2*k <= n) {int j = 2*k;if (j < n && less(pq, j, j+1)) j++;if (!less(pq, k, j)) break;exch(pq, k, j);k = j;}
}
复制代码

/*************************************************************************** * Helper functions for comparisons and swaps. * Indices are "off-by-one" to support 1-based indexing. ***************************************************************************/ private static boolean less(Comparable[] pq, int i, int j) { return pq[i-1].compareTo(pq[j-1]) < 0; }

private static void exch(Object[] pq, int i, int j) {Object swap = pq[i-1];pq[i-1] = pq[j-1];pq[j-1] = swap;
}// is v < w ?
private static boolean less(Comparable v, Comparable w) {return v.compareTo(w) < 0;
}
复制代码

/*************************************************************************** * Check if array is sorted - useful for debugging. ***************************************************************************/ private static boolean isSorted(Comparable[] a) { for (int i = 1; i < a.length; i++) if (less(a[i], a[i-1])) return false; return true; }

// print array to standard output
private static void show(Comparable[] a) {for (int i = 0; i < a.length; i++) {StdOut.println(a[i]);}
}/*** Reads in a sequence of strings from standard input; heapsorts them; * and prints them to standard output in ascending order. ** @param args the command-line arguments*/
public static void main(String[] args) {String[] a = StdIn.readAllStrings();Heap.sort(a);show(a);assert isSorted(a);
}
复制代码

}

11.归并排序 public class Solution { /** * @param A an integer array * @return void */ public void sortIntegers2(int[] A) { // use a shared temp array, the extra memory is O(n) at least int[] temp = new int[A.length]; mergeSort(A, 0, A.length - 1, temp); }

private void mergeSort(int[] A, int start, int end, int[] temp) {if (start >= end) {return;}int left = start, right = end;int mid = (start + end) / 2;mergeSort(A, start, mid, temp);mergeSort(A, mid+1, end, temp);merge(A, start, mid, end, temp);
}private void merge(int[] A, int start, int mid, int end, int[] temp) {int left = start;int right = mid+1;int index = start;// merge two sorted subarrays in A to temp arraywhile (left <= mid && right <= end) {if (A[left] < A[right]) {temp[index++] = A[left++];} else {temp[index++] = A[right++];}}while (left <= mid) {temp[index++] = A[left++];}while (right <= end) {temp[index++] = A[right++];}// copy temp back to Afor (index = start; index <= end; index++) {A[index] = temp[index];}
}
复制代码

}

12.链表倒数第k个结点 快慢指针,注意最开始 head==null||k<=0的判断和 if(fastpointer.next==null){ return dummy; }的判断 public class Solution { public ListNode FindKthToTail(ListNode head,int k) { ListNode dummy=null; if(head==null||k<=0){ return dummy; } ListNode fastpointer=head; ListNode slowpointer=head;

int i=0; while(i<k-1){ if(fastpointer.next==null){ return dummy; } fastpointer=fastpointer.next; i++; }

while(fastpointer.next!=null){ fastpointer=fastpointer.next; slowpointer=slowpointer.next; }

return slowpointer; } }

13.反转链表 public class Solution { public ListNode ReverseList(ListNode head) { ListNode next=null; ListNode pre=null;

    while(head!=null){next=head.next;head.next=pre;pre=head;head=next;}return pre;
}
复制代码

}

14.合并两个排序的链表 public class Solution { public ListNode Merge(ListNode list1,ListNode list2) {

    ListNode dummy=new ListNode(0);ListNode result=dummy;while(list1!=null&&list2!=null){if(list1.val<list2.val){result.next=list1;list1=list1.next;}else{result.next=list2;list2=list2.next;}  result=result.next;  }if (list1 != null) {result.next = list1;} else {result.next = list2;}return dummy.next;}
复制代码

}

15.连续子数组的最大和 public class Solution { public int FindGreatestSumOfSubArray(int[] array) { if(array.length==0){ return 0; }

    int result=array[0];int sum=array[0];for(int i=1;i<array.length;i++){if(sum>=0){sum=sum+array[i];}if(sum<0){sum=array[i];}if(sum>result){result=sum;}}return result;
}
复制代码

}

16.把数组排成最小的数 输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。 例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。 import java.util.ArrayList; import java.util.*; public class Solution {

public String PrintMinNumber(int [] numbers) {if(numbers.length==0||numbers==null){return "";}String[] str=new String[numbers.length];StringBuilder sb=new StringBuilder();
for(int i=0;i<numbers.length;i++){ str[i]=String.valueOf(numbers[i]);}Arrays.sort(str,new Comparator<String>(){public int compare(String s1, String s2) {String c1 = s1 + s2;String c2 = s2 + s1;return c1.compareTo(c2);}});for(int i = 0; i < str.length; i++){sb.append(str[i]);}return sb.toString();  }
复制代码

}

17.两个链表的第一个公共结点 //方法一:运用HasnMap的特性 import java.util.HashMap; public class Solution { public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) { ListNode current1 = pHead1; ListNode current2 = pHead2;

    HashMap<ListNode, Integer> hashMap = new HashMap<ListNode, Integer>();while (current1 != null) {hashMap.put(current1, null);current1 = current1.next;}while (current2 != null) {if (hashMap.containsKey(current2))return current2;current2 = current2.next;}return null;}
复制代码

}

//方法2:

public ListNode FindFirstCommonNodeII(ListNode pHead1, ListNode pHead2) { ListNode current1 = pHead1;// 链表1 ListNode current2 = pHead2;// 链表2 if (pHead1 == null || pHead2 == null) return null; int length1 = getLength(current1); int length2 = getLength(current2); // 两连表的长度差

    // 如果链表1的长度大于链表2的长度if (length1 >= length2) {int len = length1 - length2;// 先遍历链表1,遍历的长度就是两链表的长度差while (len > 0) {current1 = current1.next;len--;}}// 如果链表2的长度大于链表1的长度else if (length1 < length2) {int len = length2 - length1;// 先遍历链表1,遍历的长度就是两链表的长度差while (len > 0) {current2 = current2.next;len--;}}//开始齐头并进,直到找到第一个公共结点while(current1!=current2){current1=current1.next;current2=current2.next;}return current1;}// 求指定链表的长度
public static int getLength(ListNode pHead) {int length = 0;ListNode current = pHead;while (current != null) {length++;current = current.next;}return length;
}18.二叉树深度
复制代码

import java.util.Queue; import java.util.LinkedList;

public class Solution { public int TreeDepth(TreeNode pRoot) { if(pRoot == null){ return 0; } Queue queue = new LinkedList(); queue.add(pRoot); int depth = 0, count = 0, nextCount = 1; while(queue.size()!=0){ TreeNode top = queue.poll(); count++; if(top.left != null){ queue.add(top.left); } if(top.right != null){ queue.add(top.right); } if(count == nextCount){ nextCount = queue.size(); count = 0; depth++; } } return depth; } } 递归写法,比较简单,不解释:

import java.lang.Math; public class Solution { public int TreeDepth(TreeNode pRoot) { if(pRoot == null){ return 0; } int left = TreeDepth(pRoot.left); int right = TreeDepth(pRoot.right); return Math.max(left, right) + 1; } }

19.和为S的序列 import java.util.ArrayList; /* *初始化small=1,big=2; *small到big序列和小于sum,big++;大于sum,small++; *当small增加到(1+sum)/2是停止 */ public class Solution { public ArrayList<ArrayList> FindContinuousSequence(int sum) { ArrayList<ArrayList> lists=new ArrayList<ArrayList>(); if(sum<=1){return lists;} int small=1; int big=2; while(small!=(1+sum)/2){ //当small==(1+sum)/2的时候停止 int curSum=sumOfList(small,big); if(curSum==sum){ ArrayList list=new ArrayList(); for(int i=small;i<=big;i++){ list.add(i); } lists.add(list); small++;big++; }else if(curSum<sum){ big++; }else{ small++; } } return lists; }

public int sumOfList(int head,int leap){        //计算当前序列的和int sum=head;for(int i=head+1;i<=leap;i++){sum+=i;}return sum;
}
复制代码

}

20.约瑟夫环 class Solution { public: int LastRemaining_Solution(unsigned int n, unsigned int m) {

    if(n <= 0 && m <= 0) return -1; //蛋疼的特殊条件int t = 0;for(int i = 2; i <= n; i++)t = (t + m) % i;return t;
}
复制代码

}; /* 约瑟夫问题 递推公式 让f[i]为i个人玩游戏报m退出最后的胜利者的编号,最后的结果自然是f[n] 服了 f[1] = 0; f[i] = (f[i - 1] + m) mod i;

因为递推,所以可以不用保存状态 代码如下

*/

/约瑟夫问题,求递推公式,每轮的序列中最后出序列的数都是同一个/ public int LastRemaining_Solution(int n,int m) { if(n < 1 || m < 1) return -1; if(n == 1){ return 0; } return (LastRemaining_Solution(n-1, m)+m)%n; }

21.删除链表中重复的结点 public static ListNode deleteDuplication(ListNode pHead) {

    ListNode first = new ListNode(-1);//设置一个trickfirst.next = pHead;ListNode p = pHead;ListNode last = first;while (p != null && p.next != null) {if (p.val == p.next.val) {int val = p.val;while (p!= null&&p.val == val)p = p.next;last.next = p;} else {last = p;p = p.next;}}return first.next;
}22.之字形打印二叉树
import java.util.*;
复制代码

/* public class TreeNode { int val = 0; TreeNode left = null; TreeNode right = null;

public TreeNode(int val) {this.val = val;}
复制代码

} */

public class Solution{ public ArrayList<ArrayList> Print(TreeNode pRoot) { ArrayList<ArrayList> result = new ArrayList<ArrayList>(); if(pRoot == null){ return result; } boolean leftToRight = true; Queue layer = new LinkedList(); ArrayList layerList = new ArrayList(); layer.add(pRoot); int start = 0, end = 1; while(!layer.isEmpty()){ TreeNode cur = layer.remove(); layerList.add(cur.val); start++; if(cur.left!=null){ layer.add(cur.left);
} if(cur.right!=null){ layer.add(cur.right); } if(start == end){ end = layer.size(); start = 0;
if(!leftToRight){ result.add(reverse(layerList)); }else{ result.add(layerList); } leftToRight = !leftToRight; layerList = new ArrayList(); } } return result; } private ArrayList reverse(ArrayList layerList) {
int length = layerList.size(); ArrayList reverseList = new ArrayList(); for(int i = length-1; i >= 0;i--){ reverseList.add(layerList.get(i)); } return reverseList; } }

23.二叉树的下一个结点 /* public class TreeLinkNode { int val; TreeLinkNode left = null; TreeLinkNode right = null; TreeLinkNode next = null; (next指向父节点) TreeLinkNode(int val) { this.val = val; } } */ public class Solution { public TreeLinkNode GetNext(TreeLinkNode pNode) { if(pNode.right!=null){ pNode=pNode.right; while(pNode.left!=null){ pNode=pNode.left; }

  return pNode;}  else{if(pNode.next.left==pNode){return pNode.next;}else{while(pNode.next.left!=pNode){pNode=pNode.next;}return pNode;}}
}
复制代码

} 上面只过了25%,缺少判断是否是根节点,最后一个return 应该是pNode.next public class Solution { TreeLinkNode GetNext(TreeLinkNode pNode) { if(pNode == null){ return null; } if(pNode.right != null){ pNode = pNode.right; while(pNode.left != null){ pNode = pNode.left; } return pNode; } while(pNode.next != null){ //非根节点 if(pNode == pNode.next.left) return pNode.next; pNode = pNode.next; } return null; } }

24.二叉搜索树第k个节点 给定一颗二叉搜索树,请找出其中的第k小的结点。例如, 5 / \ 3 7 /\ /\ 2 4 6 8 中,按结点数值大小顺序第三个结点的值为4。 import java.util.Stack; public class Solution { //中序递归 int count = 0; TreeNode KthNode(TreeNode pRoot, int k) { if(count > k || pRoot == null) return null; TreeNode p = pRoot; Stack LDRStack = new Stack(); TreeNode kthNode = null; while(p != null || !LDRStack.isEmpty()){ while(p != null){ LDRStack.push(p); p = p.left; } TreeNode node = LDRStack.pop(); System.out.print(node.val+","); count++; if(count == k){ kthNode = node; } p = node.right; } return kthNode; } }

25.有一棵无穷大的满二叉树,其结点按根结点一层一层地从左往右依次编号,根结点编号为1。现在有两个结点a,b。请设计一个算法,求出a和b点的最近公共祖先的编号。 给定两个int a,b。为给定结点的编号。请返回a和b的最近公共祖先的编号。注意这里结点本身也可认为是其祖先。 //思路:满二叉树的子节点与父节点之间的关系为root = child / 2 //利用这个关系,如果a != b,就让其中的较大数除以2, 如此循环知道a == b, //即是原来两个数的最近公共祖先 //代码如下: class LCA { public: int getLCA(int a, int b) { // write code here while(a != b) { if(a > b) a /= 2; else b /= 2; } return a; } }

26.输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。 import java.util.ArrayList; import java.util.Stack; public class Solution { public ArrayList<ArrayList> FindPath(TreeNode root, int target) { ArrayList<ArrayList> pathList= new ArrayList<ArrayList>(); if(root==null) return pathList; Stack stack=new Stack(); FindPath(root,target,stack,pathList ); return pathList;

}
private void FindPath(TreeNode root, int target,Stack<Integer> path,ArrayList<ArrayList<Integer>> pathList) {if(root==null)return;if(root.left==null&&root.right==null){if(root.val==target){ArrayList<Integer> list=new ArrayList<Integer>();for(int i:path){list.add(new Integer(i));}list.add(new Integer(root.val));pathList.add(list);}}else{path.push(new Integer(root.val));FindPath(root.left, target-root.val, path, pathList);FindPath(root.right, target-root.val, path,  pathList);path.pop();}}
复制代码

}

27.对于一个字符串,请设计一个算法,判断其是否为一个合法的括号串。 给定一个字符串A和它的长度n,请返回一个bool值代表它是否为一个合法的括号串。 测试样例: "(()())",6 返回:true 测试样例: "()a()()",7 返回:false 测试样例: "()(()()",7 返回:false

//1.非递归,使用栈结构 public boolean chkParenthesis(String A, int n) { // write code here /* * 1.碰到")"开始弹出栈顶的"(",如果此时栈为空,则返回false * 2.碰到其他内容直接返回false * 3.字符串结尾时,栈非空返回false */ Stack lefts = new Stack(); if(A == null || A.length() != n){ return false; } for(int i = 0; i < n; i++){ if(A.charAt(i) == '('){ lefts.push(A.charAt(i)); }else if(A.charAt(i) == ')'){ if(lefts.empty()){ return false; }else{ lefts.pop(); } }else{ return false; } } if(!lefts.empty()){ return false; }else{ return true; } }

28.有两个用链表表示的整数,每个结点包含一个数位。这些数位是反向存放的,也就是个位排在链表的首部。编写函数对这两个整数求和,并用链表形式返回结果。
复制代码

给定两个链表ListNode* A,ListNode* B,请返回A+B的结果(ListNode*)。 测试样例: {1,2,3},{3,2,1} 返回:{4,4,4}

public class Plus { public ListNode plusAB(ListNode a, ListNode b) { if (a == null) { return b; } if (b == null) { return a; } ListNode p1 = a, p2 = b; ListNode head = new ListNode(0); ListNode p = head; int sum = 0; while (p1 != null || p2 != null || sum != 0) { if (p1 != null) { sum += p1.val; p1 = p1.next; } if (p2 != null) { sum += p2.val; p2 = p2.next; } p.next = new ListNode(sum % 10); sum /= 10; p = p.next; } return head.next; } }

29.[编程题]链表分割 编写代码,以给定值x为基准将链表分割成两部分,所有小于x的结点排在大于或等于x的结点之前 给定一个链表的头指针 ListNode* pHead,请返回重新排列后的链表的头指针。注意:分割以后保持原来的数据顺序不变。 思路

设置两个链表头,遍历原链表,一个追加小数链表,一个追加大数链表,最后将小数链表粘到大数链表前边即为结果。

class Partition { public: ListNode* partition(ListNode* head, int x) { if(head == nullptr){ return nullptr; }//if ListNode *smallList = new ListNode(-1); ListNode *bigList = new ListNode(-1); ListNode *ps = smallList,*pb = bigList,*cur = head; while(cur){ if(cur->val < x){ ps->next = cur; ps = cur; }//if else{ pb->next = cur; pb = cur; }//else cur = cur->next; }//while pb->next = nullptr; ps->next = bigList->next; return smallList->next; } }

30.树转换为链表 有一个类似结点的数据结构TreeNode,包含了val属性和指向其它结点的指针。其可以用来表示二叉查找树(其中left指针表示左儿子,right指针表示右儿子)。 请编写一个方法,将二叉查找树转换为一个链表,其中二叉查找树的数据结构用TreeNode实现,链表的数据结构用ListNode实现。 给定二叉查找树的根结点指针root,请返回转换成的链表的头指针。

Solution: 利用中序遍历,提供递归和非递归版本。

//Method 1: //递归 ListNode dummy=new ListNode(0); ListNode tail=dummy;
public ListNode treeToList(TreeNode root) { // write code here if(root==null) return null;

    treeToList(root.left);tail.next=new ListNode(root.val);tail=tail.next;treeToList(root.right);return dummy.next;
}// Method 2: iterator
public ListNode treeToList(TreeNode root) {// write code hereif(root==null) return null;ListNode dummy=new ListNode(0);ListNode tail=dummy;Stack<TreeNode> stack=new Stack<TreeNode>();        while(root!=null || !stack.isEmpty()){
复制代码

while(root!=null){ stack.push(root); root=root.left; }

        root=stack.pop();tail.next=new ListNode(root.val);tail=tail.next;root=root.right;}return dummy.next;
}31.数组中的逆序对
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。
输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007
参考《剑指offer》用归并排序的思想, 时间复杂度O(nlogn)
复制代码

int InversePairs(vector data) { int length = data.size(); return mergeSort(data, 0, length-1); }

int mergeSort(vector<int>& data, int start, int end) {// 递归终止条件if(start >= end) {return 0;}// 递归int mid = (start + end) / 2;int leftCounts = mergeSort(data, start, mid);int rightCounts = mergeSort(data, mid+1, end);// 归并排序,并计算本次逆序对数vector<int> copy(data); // 数组副本,用于归并排序int foreIdx = mid;      // 前半部分的指标int backIdx = end;      // 后半部分的指标int counts = 0;         // 记录本次逆序对数int idxCopy = end;      // 辅助数组的下标while(foreIdx>=start && backIdx >= mid+1) {if(data[foreIdx] > data[backIdx]) {copy[idxCopy--] = data[foreIdx--];counts += backIdx - mid;} else {copy[idxCopy--] = data[backIdx--];}}while(foreIdx >= start) {copy[idxCopy--] = data[foreIdx--];}while(backIdx >= mid+1) {copy[idxCopy--] = data[backIdx--];}for(int i=start; i<=end; i++) {data[i] = copy[i];}return (leftCounts+rightCounts+counts);
}
复制代码

31.反转单词顺序 //翻转str从s到e的部分 void ReverseWord(string &str, int s, int e) { while(s < e) swap(str[s++], str[e--]); }

string ReverseSentence(string str) {ReverseWord(str, 0, str.size() - 1); //先整体翻转int s = 0, e = 0;int i = 0;while(i < str.size()){while(i < str.size() && str[i] == ' ') //空格跳过i++;e = s = i; //记录单词的第一个字符的位置   while(i < str.size() && str[i] != ' ') //不是空格 找单词最后一个字符的位置{i++;e++;}            ReverseWord(str, s, e - 1); //局部翻转}return str;
}32.调整数组顺序使奇数位于偶数前面
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,
使得所有的奇数位于数组的前半部分,所有的偶数位于位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。
public void reOrderArray2(int [] a) {
if(a==null||a.length==0)return;
int i = 0,j;
while(i<a.length){while(i<a.length&&!isEven(a[i]))i++;j = i+1;while(j<a.length&&isEven(a[j]))j++;if(j<a.length){int tmp = a[j];for (int j2 = j-1; j2 >=i; j2--) {a[j2+1] = a[j2];}a[i++] = tmp;}else{// 查找失敗break;}
}
复制代码

} boolean isEven(int n){ if(n%2==0) return true; return false; }

//两个思路吧,第一个思路:类似冒泡算法,前偶后奇数就交换: class Solution { public: void reOrderArray(vector &array) {

    for (int i = 0; i < array.size();i++){for (int j = array.size() - 1; j>i;j--){if (array[j] % 2 == 1 && array[j - 1]%2 == 0) //前偶后奇交换{swap(array[j], array[j-1]);}}}
}
复制代码

};

//第二个思路:再创建一个数组 class Solution{ public: void reOrderArray(vector &array) {

    vector<int> array_temp;vector<int>::iterator ib1, ie1;ib1 = array.begin();for (; ib1 != array.end();){            //遇见偶数,就保存到新数组,同时从原数组中删除if (*ib1 % 2 == 0) {array_temp.push_back(*ib1);ib1 = array.erase(ib1);}else{ib1++;}}vector<int>::iterator ib2, ie2;ib2 = array_temp.begin();ie2 = array_temp.end();for (; ib2 != ie2; ib2++)             //将新数组的数添加到老数组{array.push_back(*ib2);}
}
复制代码

};

33.最长公共子串 Given two strings, find the longest common substring. Return the length of it. Note The characters in substring should occur continiously in original string. This is different with subsequnce.

public class Solution { /** * @param A, B: Two string. * @return: the length of the longest common substring. */ public int longestCommonSubstring(String A, String B) { // state: f[i][j] is the length of the longest lcs // ended with A[i - 1] & B[j - 1] in A[0..i-1] & B[0..j-1] int n = A.length(); int m = B.length(); int[][] f = new int[n + 1][m + 1];

    // initialize: f[i][j] is 0 by default// function: f[i][j] = f[i - 1][j - 1] + 1 or 0for (int i = 1; i <= n; i++) {for (int j = 1; j <= m; j++) {if (A.charAt(i - 1) == B.charAt(j - 1)) {f[i][j] = f[i - 1][j - 1] + 1;} else {f[i][j] = 0;}}}// answer: max{f[i][j]}int max = 0;for (int i = 1; i <= n; i++) {for (int j = 1; j <= m; j++) {max = Math.max(max, f[i][j]);}}return max;
}
复制代码

}

34.找出二叉树中和值最大的路径 Given a binary tree, find the maximum path sum. The path may start and end at any node in the tree.

For example: Given the below binary tree, 1 / \ 2 3 Return 6.

public class Solution { private class ResultType { // singlePath: 从root往下走到任意点的最大路径,这条路径可以不包含任何点 // maxPath: 从树中任意到任意点的最大路径,这条路径至少包含一个点 int singlePath, maxPath; ResultType(int singlePath, int maxPath) { this.singlePath = singlePath; this.maxPath = maxPath; } }

private ResultType helper(TreeNode root) {if (root == null) {return new ResultType(0, Integer.MIN_VALUE);}// DivideResultType left = helper(root.left);ResultType right = helper(root.right);// Conquerint singlePath = Math.max(left.singlePath, right.singlePath) + root.val;singlePath = Math.max(singlePath, 0);int maxPath = Math.max(left.maxPath, right.maxPath);maxPath = Math.max(maxPath, left.singlePath + right.singlePath + root.val);return new ResultType(singlePath, maxPath);
}public int maxPathSum(TreeNode root) {ResultType result = helper(root);return result.maxPath;
}
复制代码

}

// Version 2: // SinglePath也定义为,至少包含一个点。 public class Solution { /** * @param root: The root of binary tree. * @return: An integer. */ private class ResultType { int singlePath, maxPath; ResultType(int singlePath, int maxPath) { this.singlePath = singlePath; this.maxPath = maxPath; } }

private ResultType helper(TreeNode root) {if (root == null) {return new ResultType(Integer.MIN_VALUE, Integer.MIN_VALUE);}// DivideResultType left = helper(root.left);ResultType right = helper(root.right);// Conquerint singlePath =Math.max(0, Math.max(left.singlePath, right.singlePath)) + root.val;int maxPath = Math.max(left.maxPath, right.maxPath);maxPath = Math.max(maxPath,Math.max(left.singlePath, 0) + Math.max(right.singlePath, 0) + root.val);return new ResultType(singlePath, maxPath);
}public int maxPathSum(TreeNode root) {ResultType result = helper(root);return result.maxPath;
}
复制代码

}

35.hashMap public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable {

private static final long serialVersionUID = 362498820763181265L;/*** The default initial capacity - MUST be a power of two.*/
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16/*** The maximum capacity, used if a higher value is implicitly specified* by either of the constructors with arguments.* MUST be a power of two <= 1<<30.*/
static final int MAXIMUM_CAPACITY = 1 << 30;/*** The load factor used when none specified in constructor.*/
static final float DEFAULT_LOAD_FACTOR = 0.75f;/*** The bin count threshold for using a tree rather than list for a* bin.  Bins are converted to trees when adding an element to a* bin with at least this many nodes. The value must be greater* than 2 and should be at least 8 to mesh with assumptions in* tree removal about conversion back to plain bins upon* shrinkage.*/
static final int TREEIFY_THRESHOLD = 8;/*** The bin count threshold for untreeifying a (split) bin during a* resize operation. Should be less than TREEIFY_THRESHOLD, and at* most 6 to mesh with shrinkage detection under removal.*/
static final int UNTREEIFY_THRESHOLD = 6;/*** The smallest table capacity for which bins may be treeified.* (Otherwise the table is resized if too many nodes in a bin.)* Should be at least 4 * TREEIFY_THRESHOLD to avoid conflicts* between resizing and treeification thresholds.*/
static final int MIN_TREEIFY_CAPACITY = 64;/*** Basic hash bin node, used for most entries.  (See below for* TreeNode subclass, and in LinkedHashMap for its Entry subclass.)*//*** Computes key.hashCode() and spreads (XORs) higher bits of hash* to lower.  Because the table uses power-of-two masking, sets of* hashes that vary only in bits above the current mask will* always collide. (Among known examples are sets of Float keys* holding consecutive whole numbers in small tables.)  So we* apply a transform that spreads the impact of higher bits* downward. There is a tradeoff between speed, utility, and* quality of bit-spreading. Because many common sets of hashes* are already reasonably distributed (so don't benefit from* spreading), and because we use trees to handle large sets of* collisions in bins, we just XOR some shifted bits in the* cheapest possible way to reduce systematic lossage, as well as* to incorporate impact of the highest bits that would otherwise* never be used in index calculations because of table bounds.*/static final int hash(Object key) {int h;return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);* capacity and load factor.** @param  initialCapacity the initial capacity* @param  loadFactor      the load factor* @throws IllegalArgumentException if the initial capacity is negative*         or the load factor is nonpositive*/
public HashMap(int initialCapacity, float loadFactor) {if (initialCapacity < 0)throw new IllegalArgumentException("Illegal initial capacity: " +initialCapacity);if (initialCapacity > MAXIMUM_CAPACITY)initialCapacity = MAXIMUM_CAPACITY;if (loadFactor <= 0 || Float.isNaN(loadFactor))throw new IllegalArgumentException("Illegal load factor: " +loadFactor);this.loadFactor = loadFactor;this.threshold = tableSizeFor(initialCapacity);
}
复制代码

/** * Returns the value to which the specified key is mapped, * or {@code null} if this map contains no mapping for the key. * *

More formally, if this map contains a mapping from a key * {@code k} to a value {@code v} such that {@code (key==null ? k==null : * key.equals(k))}, then this method returns {@code v}; otherwise * it returns {@code null}. (There can be at most one such mapping.) * *

A return value of {@code null} does not necessarily * indicate that the map contains no mapping for the key; it's also * possible that the map explicitly maps the key to {@code null}. * The {@link #containsKey containsKey} operation may be used to * distinguish these two cases. * * @see #put(Object, Object) */ public V get(Object key) { Node<K,V> e; return (e = getNode(hash(key), key)) == null ? null : e.value; }

/** * Implements Map.get and related methods * * @param hash hash for key * @param key the key * @return the node, or null if none */ final Node<K,V> getNode(int hash, Object key) { Node<K,V>[] tab; Node<K,V> first, e; int n; K k; if ((tab = table) != null && (n = tab.length) > 0 && (first = tab[(n - 1) & hash]) != null) { if (first.hash == hash && // always check first node ((k = first.key) == key || (key != null && key.equals(k)))) return first; if ((e = first.next) != null) { if (first instanceof TreeNode) return ((TreeNode<K,V>)first).getTreeNode(hash, key); do { if (e.hash == hash && ((k = e.key) == key || (key != null && key.equals(k)))) return e; } while ((e = e.next) != null); } } return null; }

public V put(K key, V value) { return putVal(hash(key), key, value, false, true); }

/** * Implements Map.put and related methods * * @param hash hash for key * @param key the key * @param value the value to put * @param onlyIfAbsent if true, don't change existing value * @param evict if false, the table is in creation mode. * @return previous value, or null if none */ final V putVal(int hash, K key, V value, boolean onlyIfAbsent, boolean evict) { Node<K,V>[] tab; Node<K,V> p; int n, i; if ((tab = table) == null || (n = tab.length) == 0) n = (tab = resize()).length; if ((p = tab[i = (n - 1) & hash]) == null) tab[i] = newNode(hash, key, value, null); else { Node<K,V> e; K k; if (p.hash == hash && ((k = p.key) == key || (key != null && key.equals(k)))) e = p; else if (p instanceof TreeNode) e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value); else { for (int binCount = 0; ; ++binCount) { if ((e = p.next) == null) { p.next = newNode(hash, key, value, null); if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st treeifyBin(tab, hash); break; } if (e.hash == hash && ((k = e.key) == key || (key != null && key.equals(k)))) break; p = e; } } if (e != null) { // existing mapping for key V oldValue = e.value; if (!onlyIfAbsent || oldValue == null) e.value = value; afterNodeAccess(e); return oldValue; } } ++modCount; if (++size > threshold) resize(); afterNodeInsertion(evict); return null; }

public V remove(Object key) { Node<K,V> e; return (e = removeNode(hash(key), key, null, false, true)) == null ? null : e.value; }

/*** Implements Map.remove and related methods** @param hash hash for key* @param key the key* @param value the value to match if matchValue, else ignored* @param matchValue if true only remove if value is equal* @param movable if false do not move other nodes while removing* @return the node, or null if none*/
final Node<K,V> removeNode(int hash, Object key, Object value,boolean matchValue, boolean movable) {Node<K,V>[] tab; Node<K,V> p; int n, index;if ((tab = table) != null && (n = tab.length) > 0 &&(p = tab[index = (n - 1) & hash]) != null) {Node<K,V> node = null, e; K k; V v;if (p.hash == hash &&((k = p.key) == key || (key != null && key.equals(k))))node = p;else if ((e = p.next) != null) {if (p instanceof TreeNode)node = ((TreeNode<K,V>)p).getTreeNode(hash, key);else {do {if (e.hash == hash &&((k = e.key) == key ||(key != null && key.equals(k)))) {node = e;break;}p = e;} while ((e = e.next) != null);}}if (node != null && (!matchValue || (v = node.value) == value ||(value != null && value.equals(v)))) {if (node instanceof TreeNode)((TreeNode<K,V>)node).removeTreeNode(this, tab, movable);else if (node == p)tab[index] = node.next;elsep.next = node.next;++modCount;--size;afterNodeRemoval(node);return node;}}return null;
}}36.第一个只出现一次的字符
import java.util.*;
复制代码

public class Solution {

HashMap<Character, Integer> map = new HashMap<>();public int FirstNotRepeatingChar(String str) {if (str==null)return -1;int length = str.length();int chars[]=new int[256];for(int i = 0;i<length;i++) {if(map.containsKey(str.charAt(i))){int value = map.get(str.charAt(i));map.put(str.charAt(i),value+1);}else{map.put(str.charAt(i),1);chars[str.charAt(i)]=i;}}for(int i = 0;i<length;i++){if(map.get(str.charAt(i))==1)return chars[str.charAt(i)];}return -1;
}
复制代码

}

37.二维数组查找 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。 请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

思路:首先我们选择从左下角开始搜寻, (为什么不从左上角开始搜寻,左上角向右和向下都是递增,那么对于一个点,对于向右和向下会产生一个岔路;如果我们选择从左下脚开始搜寻的话, 如果大于就向右,如果小于就向下)。 public class Solution { public boolean Find(int [][] array,int target) { int len = array.length-1; int i = 0; while((len >= 0)&& (i < array[0].length)){ if(array[len][i] > target){ len--; }else if(array[len][i] < target){ i++; }else{ return true; } } return false; } }

38.LRU CACHE

public int get(int key) {if( !hs.containsKey(key)) {return -1;}// remove currentNode current = hs.get(key);current.prev.next = current.next;current.next.prev = current.prev;// move current to tailmove_to_tail(current);return hs.get(key).value;
}public void set(int key, int value) {if( get(key) != -1) {hs.get(key).value = value;return;}if (hs.size() == capacity) {hs.remove(head.next.key);head.next = head.next.next;head.next.prev = head;}Node insert = new Node(key, value);hs.put(key, insert);move_to_tail(insert);
}private void move_to_tail(Node current) {current.prev = tail.prev;tail.prev = current;current.prev.next = current;current.next = tail;
}
复制代码

}

39.大数据的top k 40.100个降序数组,每组500个数,找到前3000大的数

转载于:https://juejin.im/post/5a5995d16fb9a01cac181ede

JAVA面试题目及推荐书籍相关推荐

  1. Java面试题目大汇总(附参考答案)

    足足准备了长达3个月的面试,终于在上周拿到了阿里的offer! 博主汇总整理了一份我面试之前看的一些Java面试题目,可以说是非常详细! 分享给大家,希望对正在面试Java岗位的朋友有帮助哈~~ (文 ...

  2. 2021年Java面试题目最新总结【90%面试会踩的坑】

    学会java技术之后大家面临的最多的问题就是面试这关,求职面试java岗位是否能够成功是直接影响我们的工作机会的,所以对于Java程序员面试你准备好了吗?今天小编汇总了一下关于Java程序员面试,90 ...

  3. 2019蚂蚁金服 Java面试题目!涵盖现场3面真题

    蚂蚁Java一面 二叉搜索树和平衡二叉树有什么关系,强平衡二叉树(AVL树)和弱平衡二叉树(红黑树)有什么区别 B树和B+树的区别,为什么MySQL要使用B+树 HashMap如何解决Hash冲突 e ...

  4. 非常全面的阿里的Java面试题目,涵盖Java基础+高级+架构

    阿里技术一面 自我介绍 Java中多态是怎么实现的 Java中的几种锁 数据库隔离级别 脏读 幻读 ACID mysql的隔离级别 mysql索引实现,如何解决慢查询 数据库锁是怎么实现的 死锁的条件 ...

  5. 史上最全阿里Java面试题目大汇总!强烈建议收藏~

    阿里面试题目目录 技术一面(基础面试题目) 技术二面(技术深度.技术原理) 项目实战(项目模拟面试) JAVA开发技术常问的问题 阿里必会知识 阿里面试范畴 阿里面试总结 一:阿里技术一面(基础掌握牢 ...

  6. 最全蚂蚁金服高级Java面试题目(3面)

    一面: JVM数据存储模型,新生代.年老代的构造? java GC算法,什么时候会触发minor gc,什么时候会触发full gc? GC 可达性分析中哪些算是GC ROOT? 你熟悉的JVM调优参 ...

  7. 阿里巴巴Java面试题目

    [应聘]阿里巴巴Java面试题目 原文地址:http://blog.csdn.net/free0sky/article/details/7927275 见过的很全的Java知识总结,强悍的人生不需要解 ...

  8. 2021最新网易Java面试题目

    一.概述 本文主要来分析JMM内存模型,英文名JAVA Memory Model,它是与计算机硬件有关的一个概念.为了保证共享内存的正确性(可见性.有序性.原子性),内存模型定义了共享内存系统中多线程 ...

  9. 夜夜肝到秃顶,2022年Java面试题目收集整理归纳

    开始的碎碎念 本文大多是各大企业的topN题目,针对java中高级开发,本文会持续收集更新内容,如果大家有优质的Java面试题,也欢迎大家来投稿. 特意整理出这个分类的目录,方便大家平时复习和收藏哈. ...

  10. Java开发者跳槽必备:2021阿里Java面试题目大汇总

    5.高并发 6.中间件 7.之前项目经历,运用的技术,遇到的问题,如何解决,个人有什么收获和成长: 8.对于技术的热情(平时是否看些技术书籍,逛论坛,写博客,写源代码或程序等): JAVA开发技术面试 ...

最新文章

  1. html一级二级菜单,纯JS添加一级二级菜单的代码
  2. el-calendar 怎么设置上一年和下一年_为什么香港硕士一年的含金量那么高?
  3. HDU 1133 Buy the Ticket
  4. STL 中的容器们(四)
  5. sed 、awk用法
  6. 影响中国软件开发20人
  7. Windows系统经典高级技巧分享
  8. 对象存储OSS云存储
  9. tbase 之一 github setup
  10. java mac excel 中文乱码_解决mac excel中文乱码的问题
  11. python输入直角边求斜边-python 已知三条边求三角形的角度案例
  12. 敏捷开发系列学习总结(18)——Scrum Master的情景领导力模型
  13. 网页屏蔽右键,另存功能
  14. Unity为人物模型 添加动效Animator
  15. 电脑通过热点共享网络,手机连接热点可以访问其他内网
  16. 爱创课堂每日一题第五十六天-对前端界面工程师这个职位是怎么样理解的?它的前景会怎么样?...
  17. 深度学习与多层神经网络的区别
  18. Ubuntu 文件系统成为只读模式的解决办法
  19. 深圳打卡(四) 红树林与深圳湾公园
  20. 激光SLAM理论与实践 第二次作业(里程计标定)

热门文章

  1. 铲雪车(信息学奥赛一本通-T1374)
  2. ACM-ICPC2018北京网络赛 Tomb Raider(暴力)
  3. php mp4 ckplayer,ckplayer:超酷网页视频播放器
  4. 数据库原理与应用(五)专门的关系运算
  5. 人工智能之父图灵头像将登上新版50英镑钞票
  6. PhotoShop中蒙版介绍
  7. Matlab的一些常用功能
  8. 蓝桥杯 2014真题 史丰收速算
  9. EditPlus实现json格式化
  10. 计算机学院java男默女泪,最新网络用语学习笔记,看了后,男默女泪