- 查找二维数组中的数,且数组中每一行每一列都是有序的。
思路:从左下角开始,变成两条分叉,比当前数大就右移,小就上移。
public boolean Find(int target, int [][] array) {
int i=0;
int j=array.length-1;
while(i<array[0].length&&j>=0){
if(array[j][i]>target){
j--;
}else if(array[j][i]<target){
i++;
}else{
return true;
}
}
return false;
}
- 题目:请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy
思路:从后像前替换,这样后面的字符只需要移动一次就可以
public class Solution {
public String replaceSpace(StringBuffer str) {
int newlenght=0;
int spacenum=0;
//先计算出字符串空格的数量,算出替换后的字符串大小。
for(int i=0;i<str.length();i++){
if(str.charAt(i)==' '){
spacenum++;
}
}
//*2是因为本身就有一个空格
int oldindex=str.length()-1;
newlenght=str.length()+spacenum*2;
str.setLength(newlenght);
for(int i=newlenght-1;i>-1;i--,oldindex--){
if(str.charAt(oldindex)==' '){
str.setCharAt(i--,'0');
str.setCharAt(i--,'2');
str.setCharAt(i,'%');
}else{
str.setCharAt(i,str.charAt(oldindex));
}
}
return str.toString();
}
}
- t题目:输入一个链表,按链表值从尾到头的顺序返回一个ArrayList。
思路:递归解决
public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
ArrayList<Integer> array=new ArrayList<Integer>();
if(listNode==null){
return array;
}
//从尾到头,直接用递归
if(listNode.next==null){
array.add(listNode.val);
return array;
}else{
array=printListFromTailToHead(listNode.next);
array.add(listNode.val);
return array;
}
}
- 题目:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
思路:(大神提供的思路)递归思想,每次将左右两颗子树当成新的子树进行处理,中序的左右子树索引很好找,前序的开始结束索引通过计算中序中左右子树的大小来计算,然后递归求解,直到startPre>endPre||startIn>endIn说明子树整理完到。方法每次返回左子树活右子树的根节点
public class Solution {
public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
return subTree(pre,in,0,pre.length-1,0,in.length);
}
private TreeNode subTree(int [] pre,int [] in,int startpre,int endpre,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=subTree(pre,in,startpre+1,startpre+i-startin,startin,i);
root.right=subTree(pre,in,startpre+i-startin+1,endpre,i+1,endin);
break;
}
}
return root;
}
}
- 题目:用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。
思路:注意点就是pop时一定要先注意stack2为空时再将stack1的添加进去,不然pop出来的就是最新推进去的代码。
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(stack2.empty()){
while(!stack1.empty()){
stack2.push(stack1.pop());
}
}
Integer result=stack2.pop();
return result;
}
}
- 大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0)。
思路,找出哪一个不变的变量,用减或加的方法重复使用他,就i不用多创建太多变量,节省空间了。
int temp=0;
int temp1=1;
while(n-->0){
temp1+=temp;
temp=temp1-temp;
}
return temp;
- 一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。
参考链接:https://www.nowcoder.com/questionTerminal/8c82a5b80378478f9484d87d1c5f12a4
思路:
a.如果两种跳法,1阶或者2阶,那么假定第一次跳的是一阶,那么剩下的是n-1个台阶,跳法是f(n-1);
b.假定第一次跳的是2阶,那么剩下的是n-2个台阶,跳法是f(n-2)
c.由a\b假设可以得出总跳法为: f(n) = f(n-1) + f(n-2)
d.然后通过实际的情况可以得出:只有一阶的时候 f(1) = 1 ,只有两阶的时候可以有 f(2) = 2
e.可以发现最终得出的是一个斐波那契数列:。
当然也可以用递归会开销很大,如果不想用递归可以看上一题。
public int JumpFloor(int target) {
if(target==1){
return 1;
}else if(target==2){
return 2;
}else{
return JumpFloor(target-1)+JumpFloor(target-2);
}
}
- 一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
思路:f(n)为跳法数
1)n = 1时,只有1种跳法,f(1) = 1
2) n = 2时,会有两个跳得方式,一次1阶或者2阶,这回归到了问题(1) ,f(2) = f(2-1) + f(2-2)
3)
由
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),
也是一个是一个斐波那契数列
public int JumpFloorII(int target) {
if(target<=0){
return 0;
}else if(target==1){
return 1;
}else{
return 2*JumpFloorII(target-1);
}
}
- 我们可以用21的小矩形横着或者竖着去覆盖更大的矩形。请问用n个21的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?
思路:竖着放一块小矩形的话,剩下的摆放方法就还剩下
f(target-1),横着放的话,放了第一块的时候。**第一块下方那一块的位置也确定了 ,**所以剩下的摆放方法为f(target-2),还是斐波那契数列。
public int RectCover(int target) {
if(target<=0){
return 0;
}else if(target==1){
return 1;
}else if(target==2){
return 2;
}else{
return RectCover(target-1)+RectCover(target-2);
}
}
- 输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
思路,有两种
- 使用1右移到0来对每个位进行&运算结果不为0则判断该位是否有1.
//利用1进行右移来进行判断每一位是否为1.
int count=0;
int flag=1;
while(flag!=0){
if((n&flag)!=0){
count++;
}
flag=flag<<1;
}
return count;
-通过(n-1)&n使n的每次移动都移动所有的1位
//最优解
int count=0;
while(n!=0){
count++;
n=(n-1)&n;
}
return count;