如果你碰巧点进来想看解题思路的话,可以看下这位dalao写的.挺详细的~
https://blog.csdn.net/flushhip/article/details/79392028#commentBox
题目:在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。(链接)
解析:矩阵是有序的,从左下角来看,向上数字递减,向右数字递增。
因此从左下角开始查找,当Target比左下角数字大时——右移;Target比左下角数字小时——上移。
public class Solution {
public boolean Find(int target, int [][] array) {
int row = array.length-1;
int col = 0;
while( row>=0 && col<array[0].length ){
if(target==array[row][col])
return true;
else if(target > array[row][col])
col++;
else
row--;
}
return false;
}
}
题目:请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。(链接)
解析:从左到右遍历“ ”数量,扩大字符串容量(防止下标越界),从右到左替换。
public class Solution {
public String replaceSpace(StringBuffer str) {
int count = 0; //空格总数
int i = 0;
for(; i < str.length(); i++){
if(str.charAt(i)==' ')
count++;
}
i--;
str.setLength( str.length() + count * 2 );
for(int j = str.length()-1; count>0; i--){
if(str.charAt(i)!=' ')
str.setCharAt(j--, str.charAt(i));
//str.charAt(j)=str.charAt(i);
else{
str.setCharAt(j--, '0');
str.setCharAt(j--, '2');
str.setCharAt(j--, '%');
count--;
}
}
return str.toString();
}
}
题目:输入一个链表,按链表值从尾到头的顺序返回一个ArrayList。(链接)
解析:(先进后出) 两种方法: ①递归 ②堆栈(java.util.Stack)
/**
* public class ListNode {
* int val;
* ListNode next = null;
*
* ListNode(int val) {
* this.val = val;
* }
* }
*/
import java.util.ArrayList;
public class Solution {
ArrayList<Integer> arr = new ArrayList<Integer>();
public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
if(listNode!=null){
printListFromTailToHead(listNode.next);
arr.add(listNode.val);
}
return arr;
}
}
import java.util.ArrayList;
import java.util.Stack;
public class Solution {
public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
Stack <Integer> stack = new Stack <Integer>();
while(listNode!= null){
stack.push(listNode.val);
listNode = listNode.next;
}
ArrayList <Integer> list = new ArrayList <Integer>();
while(!stack.isEmpty()){
list.add(stack.pop());
}
return list;
}
}
题目:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。(链接)
解析:利用前序遍历第一个数字为根,用这个根在中序遍历中查找,左边的就是左子树,右边的就是右子树,算出左右子树的长度,用其长度在前序遍历中划分出左右子树,重复上述过程,就可以重建这颗二叉树了。
/**
* 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) {
TreeNode root = reConstructBinaryTree(pre,0,pre.length-1,in,0,in.length-1);
return root;
}
public TreeNode reConstructBinaryTree(int []pre, int startPre, int endPre, int []in, int startIn, int endIn) {
if(startPre>endPre || startIn>endIn)
return null;
TreeNode root = new TreeNode(pre[startPre]);
for(int i=startIn;i<=endIn;i++) {
if(in[i]==pre[startPre]) {
root.left = reConstructBinaryTree(pre,++startPre,startPre+(i-startIn),in,startIn,i-1);
root.right = reConstructBinaryTree(pre,startPre+(i-startIn),endPre,in,i+1,endIn);
break;
}
}
return root;
}
}
题目:用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。(链接)
解析:判断进时,栈2是否为空,不为空,则栈2元素倒回到栈1;出时,将栈1元素全部弹到栈2中,直到栈1为空。
1,元素先依次进入栈1,再从栈1依次弹出到栈2,然后弹出栈2顶部的元素,整个过程就是一个队列的先进先出
2,但是在交换元素的时候需要判断两个栈的元素情况:
①“进队列时”,队列中是否还有元素,若有,说明栈2中的元素不为空,此时就先将栈2的元素倒回到栈1 中,保持在“进队列状态”。
②“出队列时”,将栈1的元素全部弹到栈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) {
while(!stack2.empty()){
stack1.push(stack2.pop());
}
stack1.push(node);
}
public int pop() {
while(!stack1.empty()){
stack2.push(stack1.pop());
}
return stack2.pop();
}
}
题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素。 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。 NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。(链接)
解析:想的不够全,之后再改改。
import java.util.ArrayList;
public class Solution {
public int minNumberInRotateArray(int [] array) {
if(array.length==0)
return 0;
int l=0, r=array.length-1;
while( l<r && array[l]>=array[r] ){
int mid = (l+r)/2;
if(array[l]==array[r] && array[l]==array[mid]){
int min = array[l];
return min;
}
if(array[mid]>=array[l])
l=mid+1;
else
r=mid;
}
return array[l];
}
}
题目:大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0)。n<=39(链接)
解析:斐波拉契数列的定义:
(int型整数只能保存F0→F46)
public class Solution {
public int Fibonacci(int n) {
if(n==0)
return 0;
if(n==1)
return 1;
int f0=0,f1=1,ret=0;
for(int i=2; i<=n; i++){
ret=f0+f1;
f0=f1;
f1=ret;
}
return ret;
}
}
题目:一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。(链接)
解析:最简单的动态规划,考虑最后跳上第n阶台阶,有两种方式往上跳:
从第n - 1阶往上跳一级到第n阶;
从第n - 2阶往上跳二级到第n阶。
那么f(i)表示该青蛙跳上一个i级的台阶总共跳法。故f(i)=f(i−1)+f(i−2),f(0)=f(1)=1
这就是变形版的斐波拉契数列啊,直接求解。
【比较倾向于找规律的解法,f(1) = 1, f(2) = 2, f(3) = 3, f(4) = 5, 可以总结出f(n) = f(n-1) + f(n-2)的规律,但是为什么会出现这样的规律呢?假设现在6个台阶,我们可以从第5跳一步到6,这样的话有多少种方案跳到5就有多少种方案跳到6,另外我们也可以从4跳两步跳到6,跳到4有多少种方案的话,就有多少种方案跳到6,其他的不能从3跳到6什么的啦,所以最后就是f(6) = f(5) + f(4);】
public class Solution {
public int JumpFloor(int target) {
if(target == 1)
return 1;
if(target == 2)
return 2;
int f1=1,f2=2,ret=0;
for(int i=3;i<=target;i++){
ret=f1+f2;
f1=f2;
f2=ret;
}
return ret;
}
}
题目:一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。(链接)
解析:f(n) = f(n-1) + f(n-2) + f(n-3) + … + f(n-(n-1)) + f(n-n) => f(0) + f(1) + f(2) + f(3) + … + f(n-1)
继续简化:
f(n-1) = f(0) + f(1)+f(2)+f(3) + … + f((n-1)-1) = f(0) + f(1) + f(2) + f(3) + … + f(n-2)
f(n) = f(0) + f(1) + f(2) + f(3) + … + f(n-2) + f(n-1) = f(n-1) + f(n-1)
可以得出:
f(n) = 2*f(n-1)
① 得出最终结论,在n阶台阶,一次有1、2、…n阶的跳的方式时,总得跳法为:
f(n) = | 1 ,(n=1 )
| 2*f(n-1),(n>=2)
② 这是一个首项为1,公比为2的等比数列啊,可得到最终表达式:f(n)=2n−1
public class Solution {
public int JumpFloorII(int target) {
if(target == 1)
return 1;
int f=1,fn=0;
for(int i=2;i<=target;i++){
fn=2*f;
f=fn;
}
return fn;
}
}
public class Solution {
public int JumpFloorII(int target) {
return 1<<(target-1);
}
}
题目:我们可以用21的小矩形横着或者竖着去覆盖更大的矩形。请问用n个21的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?(链接)
解析:依旧是斐波那契数列:f(n)=f(n−1)+f(n−2),f(1)=1,f(2)=2
public class Solution {
public int RectCover(int target) {
if(target==1)
return 1;
if(target==2)
return 2;
int f1=1,f2=2,fn=0;
for(int i=3;i<=target;i++){
fn=f1+f2;
f1=f2;
f2=fn;
}
return fn;
}
}