1.请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。
思路:将原来字符串放入StringBuff对象中,对员字符串的字符进行判断是否是 ‘ ‘ ’,用charAt()方法在对应的下标取值,如果是,就在StringBuff对象上添加“%”“2”“0”,用append方法;
public class Solution {
public String replaceSpace(StringBuffer str) {
if(str==null){
return null;
}
StringBuffer NewStr=new StringBuffer();
for(int i=0;i<str.length();i++){
if(str.charAt(i) ==' '){
NewStr.append('%');
NewStr.append('2');
NewStr.append('0');
}else{
NewStr.append(str.charAt(i));
}
}
return NewStr.toString();
}
}
2.在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
思路:从左往右递增;上往下递减;那么如果我们以最左下角位置值作为最开始与传进来的值做对比的话;当传进来的值比左下角的值大时,就需要往右移动;如果传进来的值比左下角的值小时,就需要往上移动;如果相等,则返回true,否则false;
class Solution {
bool Find(vector<vector<int> > array,int target) {
int rowCount = array.size();
int colCount = array[0].size();
int i,j;
for(i=rowCount-1,j=0;i>=0&&j<colCount;)
{
if(target == array[i][j])
return true;
if(target < array[i][j])
{
i--;
continue;
}
if(target > array[i][j])
{
j++;
continue;
}
}
return false;
}
};
3.输入一个链表,按链表值从尾到头的顺序返回一个ArrayList。
思路:原题需要我们将链表从尾到头;可以利用Stack栈的先进后出的特性;
先将listNode各个节点的值逐一放入Stack栈中;再让ArrayList的add方法添加Stack吐出来的值;这样就形成了倒叙;
listNode.val-----取节点值;listNode.next----下一个节点
Stack 的push(val)方法—入栈 Stack的pop()-----出栈
import java.util.Stack;
import java.util.ArrayList;
public class Solution {
public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
Stack<Integer> stack = new Stack<>();
while (listNode != null) {
stack.push(listNode.val);
listNode = listNode.next;
}
ArrayList<Integer> list = new ArrayList<>();
while (!stack.isEmpty()) {
list.add(stack.pop());
}
return list;
}
}
4.用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。
思路:队列特点就是先进先出;用两个栈实现的话,将数据放入stack1的第一个是最后出来,如果将stack1的值吐出,给stack2的话;先进stack1的就处于stack2的顶部,后进stack1的在Stack2的底部;(类似于往桶里1倒,桶1再往桶2倒,桶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() {
while(!stack1.isEmpty()){
stack2.push(stack1.pop());
}
int first=stack2.pop();
while(!stack2.isEmpty()){
stack1.push(stack2.pop());
}
return first;
}
}
5.大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0)。(1,1,2,3,5,8…)第三个起,都等于前两个之和
n<=39
public class Solution {
public int Fibonacci(int n) {
int a=1,b=1,c=0;
if(n<0){
return 0;
}else if(n==1||n==2){
return 1;
}else{
for (int i=3;i<=n;i++){
c=a+b;
b=a;
a=c;
}
return c;
}
}
}
6.一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。
思路:分析
对于本题,前提只有 一次 1阶或者2阶的跳法。
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 class Solution {
public int JumpFloor(int target) {
if (target <= 0) {
return -1;
} else if (target == 1) {
return 1;
} else if (target ==2) {
return 2;
} else {
return JumpFloor(target-1)+JumpFloor(target-2);
}
}
}
7.一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
关于本题,前提是n个台阶会有一次n阶的跳法。分析如下:
f(1) = 1
f(2) = f(2-1) + f(2-2) //f(2-2) 表示2阶一次跳2阶的次数。
f(3) = f(3-1) + f(3-2) + f(3-3)
…
f(n) = f(n-1) + f(n-2) + f(n-3) + … + f(n-(n-1)) + f(n-n)
说明:
1)这里的f(n) 代表的是n个台阶有一次1,2,…n阶的 跳法数。
2)n = 1时,只有1种跳法,f(1) = 1
-
n = 2时,会有两个跳得方式,一次1阶或者2阶,这回归到了问题(1) ,f(2) = f(2-1) + f(2-2)
-
n = 3时,会有三种跳得方式,1阶、2阶、3阶,
那么就是第一次跳出1阶后面剩下:f(3-1);第一次跳出2阶,剩下f(3-2);第一次3阶,那么剩下f(3-3)
因此结论是f(3) = f(3-1)+f(3-2)+f(3-3)
-
n = n时,会有n中跳的方式,1阶、2阶…n阶,得出结论:
f(n) = f(n-1)+f(n-2)+…+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)
public class Solution {
public int JumpFloorII(int target) {
if (target <= 0) {
return -1;
} else if (target == 1) {
return 1;
} else {
return 2 * JumpFloorII(target - 1);
}
}
}
8.输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
分析:直接可以用Integer的toBinaryString(int)将这个数转化为二进制数,再用
toCharArray()方法转化为字符数组,就可以直接对数组进行操作;
public class Solution {
public int NumberOf1(int n) {
int m=0;
char a[]=Integer.toBinaryString(n).toCharArray();
for(int i=0;i<a.length;i++){
if(a[i]=='1'){
m++;
}
}
return m;
}
}
public class Solution {
public int NumberOf1(int n) {
int m=0;
String a=Integer.toBinaryString(n).toString();
for(int i=0;i<a.length();i++){
if(a.charAt(i)=='1'){
m++;
}
}
return m;
}
}
注意:String字符串是没有length属性的,只有length()方法
9.给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。
public class Solution {
public double Power(double base, int exponent) {
//由于exponent是int类型的整数,则可能包含正整数、0以及负整数三种情况。
double temp=1;
if(exponent>0){
for(int i=1;i<=exponent;i++){
temp=temp*base;
if(temp>1.7976931348623157E308){
System.out.println("已经超出double类型的取值范围。");
return -1;
}
}
return temp;
}if(exponent<0){
exponent=-exponent;
for(int i=1;i<=exponent;i++){
temp=temp*base;
if(temp>1.7976931348623157E308){
System.out.println("已经超出double类型的取值范围。");
return -1;
}
}
temp=1.0/temp;
return temp;
}else{
return 1;
}
}
}
10.输入一个链表,输出该链表中倒数第k个结点。
思路:定义两个指针,同时指向头结点,先让第一个指针往后移动(k-1)个,然后两个指针同时往后移动,知道第一个指针到末尾位置,此时第二个指针恰好是指在倒数第k个的位置;
public class Solution {
public ListNode FindKthToTail(ListNode head,int k) {
if(head==null||k<=0){
return null;
}
ListNode pre=head;
ListNode last=head;
for(int i=1;i<k;i++){
if(pre.next!=null){
pre=pre.next;
}else{
return null;
}
}
while(pre.next!=null){
pre = pre.next;
last=last.next;
}
return last;
}
}
11.输入一个链表,反转链表后,输出新链表的表头。
public class Solution {
public ListNode ReverseList(ListNode head) {
if(head==null){
return null;
}
//pre为head前面的节点;head;next为head后面的节点
// pre <------ head <----- next
ListNode pre =null;
ListNode next=null;
while(head!=null){
next=head.next;//next保存head.next的地址,防止断裂找不着后面的链
head.next=pre;//head指向pre pre<---head
pre=head;//pre往后移动 null<--pre(head)
head=next;//head往后移动 null<--pre(原第一节点) head(二)-->[]--->[]
}
return pre;
}
}
12.输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。
public class Solution {
public ListNode Merge(ListNode list1,ListNode list2) {
//新建一个头节点,用来存合并的链表。
ListNode head=new ListNode(-1);
head.next=null;
ListNode root=head;
while(list1!=null&&list2!=null){
if(list1.val<list2.val){
head.next=list1;
head=list1;
list1=list1.next;
}else{
head.next=list2;
head=list2;
list2=list2.next;
}
}
//把未结束的链表连接到合并后的链表尾部
if(list1!=null){
head.next=list1;
}
if(list2!=null){
head.next=list2;
}
return root.next;
}
}