适逢实习招聘,虽然自己的剑指offer已经刷过一遍,但是深感记忆的有限性。
纸笔不如博文,在此写下自己对于剑指offer上题目的总结。
目标是以精简的语言写出思路,以便自己以后翻阅。
1.二维数组中的查找
题目描述
代码如下:
public class Solution {
public boolean Find(int target, int [][] array) {
int rows = array.length; //得到行数
int cols = array[0].length; //得到列数
int i=rows-1,j=0;
while(i>=0 && j<cols){
if(target<array[i][j])
i--;
else if(target>array[i][j])
j++;
else
return true;
}
return false;
}
}
因为行列的数字排列均有序,本题可以采用对每行采用二分排序的方法来对每行进行查找,从而达到O(nlogn)的复杂度
但是可以从第rows-1行,第0列开始,判断数组的数字与所求target之间的大小,这样所走的路程不会超过行列数之和,复杂度为O(m+n)
2.替换空格
题目描述
public class Solution {
public String replaceSpace(StringBuffer str) {
StringBuffer str1 = new StringBuffer();
String str2 = str.toString();
for(int i = 0 ; i<str2.length();i++){
if(str2.charAt(i)!=' '){
str1.append(str2.charAt(i));
}
else {str1.append("%20");};
}
return str1.toString() ;
}
}
本题输入的是一个StringBuffer类。本题考查的是java中String族的API。
StringBuffer.toString()返回一个String对象
String.charAt(i) 返回第i个char类型的字符
因为本题是将字符进行替换,所以可以判断string.charAt是否为' ' if-then地将结果append到StringBuffer上,因为StringBuffer可变,可以用来节省内存。
最后用toString()方法来返回一个String对象
我们总结一下String族的异同:
1.三者在执行速度方面的比较:StringBuilder > StringBuffer > String
String最慢的原因:
String为字符串常量,而StringBuilder和StringBuffer均为字符串变量,即String对象一旦创建之后该对象是不可更改的,但后两者的对象是变量,是可以更改的。
2. 再来说线程安全
在线程安全上,StringBuilder是线程不安全的,而StringBuffer是线程安全的
如果一个StringBuffer对象在字符串缓冲区被多个线程使用时,StringBuffer中很多方法可以带有synchronized关键字,所以可以保证线程是安全的,但StringBuilder的方法则没有该关键字,所以不能保证线程安全,有可能会出现一些错误的操作。所以如果要进行的操作是多线程的,那么就要使用StringBuffer,但是在单线程的情况下,还是建议使用速度比较快的StringBuilder。
3. 总结一下
String:适用于少量的字符串操作的情况
StringBuilder:适用于单线程下在字符缓冲区进行大量操作的情况
StringBuffer:适用多线程下在字符缓冲区进行大量操作的情况
3.从尾到头打印链表
题目描述
代码如下:
/**
* public class ListNode {
* int val;
* ListNode next = null;
*
* ListNode(int val) {
* this.val = val;
* }
* }
*
*/
import java.util.ArrayList;
public class Solution {
ArrayList<Integer> arrayList=new ArrayList<Integer>();
public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
if(listNode!=null){
this.printListFromTailToHead(listNode.next);
arrayList.add(listNode.val);
}
return arrayList;
}
}
本题输入一个List Node类型的结点,根据上述定义,ListNode节点:有一个val ,一个next指针(?),一个构造函数。
看题意,本题输入一个ListNode,返回一个ArrayList。
假如我们采用从头到尾,每次加入一个节点的方法(链表只有next指针),时间复杂度过大。
所以我们采用递归的思想。
当节点的下一个值不为null时,则将其next放入原函数,同时在之后将其值放入ArrayList中,这样,当我们运行到链表的尾部时,函数返回此arrayList,同时,将此ListNode节点的值也加入了arraylist中,最后返回的arraylist中,存放的便是从尾到头的链表的val。
4.重建二叉树
题目描述
代码如下:
/**
* Definition for binary tree
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Solution {
public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
return reConBTree(pre,0,pre.length-1,in,0,in.length-1);
}
public TreeNode reConBTree(int [] pre,int preleft,int preright,int [] in,int inleft,int inright){
if(preleft > preright || inleft> inright)//当到达边界条件时候返回null
return null;
//新建一个TreeNode
TreeNode root = new TreeNode(pre[preleft]);
//对中序数组进行输入边界的遍历
for(int i = inleft; i<= inright; i++){
if(pre[preleft] == in[i]){
//重构左子树,注意边界条件
root.left = reConBTree(pre,preleft+1,preleft+i-inleft,in,inleft,i-1);
//重构右子树,注意边界条件
root.right = reConBTree(pre,preleft+i+1-inleft,preright,in,i+1,inright);
}
}
return root;
}
}
对二叉树进行递归,由于先序遍历的第一个节点是根节点,所以在中序遍历中找寻该值。
将此树的左子树 和 右子树进行递归。
5.用2个栈实现队列
题目描述
import java.util.Stack;
public class Solution {
Stack<Integer> stack1 = new Stack<Integer>();
Stack<Integer> stack2 = new Stack<Integer>();
public void push(int node) {
stack1.push(node);
}
public int pop() {
if(stack1.empty()&&stack2.empty()){
throw new RuntimeException("Queue is empty!");
}
if(!stack2.empty()){
return stack2.pop();
}
else {
while(!stack1.empty()){
stack2.push(stack1.pop());
}
return stack2.pop();
}
}
}
每当push时,直接将值压入push栈中。
每当pop时,需要考虑pop栈的情况,如果pop栈非空,则弹出最顶端节点,如果pop栈为空,则将push栈中内容全部放入pop栈中,然后pop出顶端节点。此时push pop结果与队列相同。
6.旋转数组的最小数字
题目描述
public class Solution {
public int minNumberInRotateArray(int [] array) {
int low = 0 ; int high = array.length - 1;
while(low < high){
int mid = low + (high - low) / 2;
if(array[mid] > array[high]){
low = mid + 1;
}else if(array[mid] == array[high]){
high = high - 1;
}else{
high = mid;
}
}
return array[low];
}
}
本系列暂定为牛客网上的66题,分11篇。