前言:这些算法题来源包括但不限于牛客,领扣,面试题等,有些有大佬的解答(看了感觉自己弱爆了),有些只有自己的,自己做的附有自己的解题思路,大佬的当然也有大佬的思路。

一、

在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,
每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
思路:
1 2 6 9
2 6 8 10
6 9 13 15
10 13 45 46
x=8
由于每行数据是递增的,如x=8,那么 x 可能在第一行1<8<9,也可能在第二行2<8<10,同理也可能在第三行,不会在第四行
然后在可能的行中遍历,即可知道x是否在数组中.

解答:

public boolean Find(int target, int [][] array) {
  if(array[0].length==0)
    return false;
  int leng = array.length;
  int cleng=array[0].length;
  int rnum=leng,cnum=cleng;
  for(int i=0;i<leng;i++){
    if(array[i][0]<=target&&array[i][cleng-1]>=target) {
      for (int j=0;j<cleng;j++) {
        if(target==array[i][j]){
          return true;
        }
      }
    }
  }
  return false;
}

二、

请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.
则经过替换之后的字符串为We%20Are%20Happy。
思路:
StringBuffer 没有replaceAll()方法,所以用 StringBuffer.toString()方法转为String类型,若String转StringBuffer则通过构造方法,方法:
String s="这是一个字符串";
StringBuffer sb = new StringBuffer(s);

解答:

public String replaceSpace(StringBuffer str) {
  return str.toString().replaceAll(" ","%20");
}

三、

把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素。 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。 NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
思路:
  1.冒泡排序

  2.应该用三次翻转也行吧(暂时没空写代码,匿)

解答:
public int minNumberInRotateArray(int [] array) {
  if(array.length==0)
    return 0;
  int temp;
  int leng=array.length;
  for(int i=0;i<leng;i++){
    for(int j=i+1;j<leng;j++){
      if(array[j]<array[i]){
      temp = array[i];
      array[i]=array[j];
      array[j]=temp;
      }
    }
  }
  return array[0];
}

四、

大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0)。
n<=39
斐波那契数列: 1、1、2、3、5、8、13、21、34、……在数学上,斐波纳契数列以如下被以递推的方法定义:F(1)=1,F(2)=1, F(n)=F(n-1)+F(n-2)(n>=3,n∈N*)
思路:
  递归方法

解答:
public static int f(int x){
  if(x<=1)
    return x;
  return f(x-1)+f(x-2);
}

五、

一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。
思路:
比较倾向于找规律的解法,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 static int JumpFloor(int target) {
  if(target<3)
    return target;
  /*使用递归算法
    return JumpFloor(target-1)+JumpFloor(target-2);*/
  /*使用迭代*/
  int first=1,second=2,third=0;
  for(int i=3;i<=target;i++){
    third =first +second;
    first = second;
    second=third;
  }
  return third;
}

递归算法时间复杂度非常之高,此题中复杂度在800-990ms之间,而迭代的时间复杂度为15ms。

六、

(大佬!)

一只青蛙一次可以跳上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
3) n = 2时,会有两个跳得方式,一次1阶或者2阶,这回归到了问题(1) ,f(2) = f(2-1) + f(2-2)
4) 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)
5) 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)
6) 由以上已经是一种结论,但是为了简单,我们可以继续简化:
  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)

7) 得出最终结论,在n阶台阶,一次有1、2、...n阶的跳的方式时,总得跳法为:

    | 1 ,(n=0 )
f(n) =      | 1 ,(n=1 )
              | 2*f(n-1),(n>=2)
思路:
因为n级台阶,第一步有n种跳法:跳1级、跳2级、到跳n级
跳1级,剩下n-1级,则剩下跳法是f(n-1)
跳2级,剩下n-2级,则剩下跳法是f(n-2)
所以f(n)=f(n-1)+f(n-2)+...+f(1)
因为f(n-1)=f(n-2)+f(n-3)+...+f(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);
    }
  }
}

七、

输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。

解答(自己):
public int NumberOf1(int n) {
  int shang=Integer.MAX_VALUE;
  int yushu;
  int sum=0;
  if(n>0) {
    while (shang != 0) {
    shang = n / 2;
    yushu = n % 2;
    if (yushu == 1)
    sum++;
    n = shang;
    }
  }else if (n<0){
    n = Integer.MAX_VALUE+n+1;
    sum=1;
    while (shang != 0) {
    shang = n / 2;
    yushu = n % 2;
    if (yushu == 1)
      sum++;
    n = shang;
    }
  }
  else {
    return 0;
  }
  return sum;
}
思路:
如果一个整数不为0,那么这个整数的二进制至少有一位是1。如果我们把这个整数减1,那么原来处在整数最右边的1就会变为0,原来在1后面的所有的0都会变成1(如果最右边的1后面还有0的话)。其余所有位将不会受到影响。
举个例子:一个二进制数1100,从右边数起第三位是处于最右边的一个1。减去1后,第三位变成0,它后面的两位0变成了1,而前面的1保持不变,因此得到的结果是1011.我们发现减1的结果是把最右边的一个1开始的所有位都取反了。这个时候如果我们再把原来的整数和减去1之后的结果做与运算,从原来整数最右边一个1那一位开始所有位都会变成0。如1100&1011=1000.也就是说,把一个整数减去1,再和原整数做与运算,会把该整数最右边一个1变成0.那么一个整数的二进制有多少个1,就可以进行多少次这样的操作。

解答(大佬):

public int NumberOf1(int n) {
  int count = 0;
  while(n!= 0){
    count++;
    n = n & (n - 1);
  }
  return count;
}
例子: n=11,11=1011, return 3
n=n&(n-1), 即: 1011&1010=1010
n=n&(n-1), 即: 1010&1001=1000
n=n&(n-1), 即: 1000&0111=0000

八、

输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,
所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。
思路:
遍历数组中每一个数字,奇数放在ListA中,偶数放在ListB中,然后再A,B重新赋给Array

解答(自己):
public void reOrderArray(int [] array) {
  ArrayList a = new ArrayList();
  ArrayList b = new ArrayList();
  for(int c:array){
    if(c%2==1)
    a.add(c);
  else
    b.add(c);
  }
  for(int i=0;i<a.size();i++){
    array[i]=(int)a.get(i);
  }
  for(int i=0;i<b.size();i++){
    array[i+a.size()]=(int)b.get(i);
  }
}

思路:类似冒泡算法,前偶后奇数就交换

解答(大佬):

void reOrderArray(vector<int> &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]);
      }
    }
  }

九、

一个数组中有n对相同数字,有一个不同数字,找出不同数字,数组为空则返回0。
思路:
int[] numarry = new int[]{1,2,3,2,3};
关于上边的这个结果是什么,你只需要知道异或运算的特点就可以了,比如1,2,3,2,3 ,既然异或运算满足上边的交换规则,对于1^2^3^2^3 这样的异或运算,我们换一下位置(2^2)^(3^3)^1 ,通过两个相同的数进行异或运算得到0 ,那最终就会是0^0^1 ,最后会得到1 。

解答(大佬):

public static int selectNum(int[] x){
  if(x.length==0)
    return 0;
  int num=x[0];
  for(int i=1;i<x.length;i++)
    num = num ^ x[i];
  return num;
}

十、

用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。
思路:
进队操作则对stack1进行push,出队操作分为两种,当stack2不为空时,则对stack2进行pop,若stack2为空,则将stack1 pop出的数据push入stack2,
再对stack2进行pop,若stack1也为空,则NullPointException

解答:
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(!stack2.empty())
      return stack2.pop();
    while(!stack1.empty()){
      stack2.push(stack1.pop());
    }
    return stack2.pop();
  }
}

十一、

输入一个链表,按链表值从尾到头的顺序返回一个ArrayList。
/*
public class ListNode {
  int val;
  ListNode next = null;

  ListNode(int val) {
    this.val = val;
  }
}*/

思路:
将链表里的值取出放到ArrayList中,然后利用Collections里的reverse()方法反转ArrayList

解答:
import java.util.ArrayList;
import java.util.Collections;

public static ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
  ArrayList<Integer> newI= new ArrayList<Integer>();
  if(listNode!=null) {
    newI.add(listNode.val);
    while (listNode.next != null) {
      listNode = listNode.next;
      newI.add(listNode.val);
    }
    Collections.reverse(newI);
  }
  return newI;
}

思路:

利用栈先进后出的原理,先将链表里的值压入栈中,再将栈中的值取出放入ArrayList

public static ArrayList<Integer> printListFromTailToHead(Person listNode) {
  ArrayList<Integer> newI= new ArrayList<Integer>();
  Stack<Integer> sta = new Stack<Integer>();
  /*压入栈*/
  if(listNode!=null)
  {
    sta.push(listNode.val);
    while(listNode.next!=null){
      sta.push(listNode.next.val);
      listNode = listNode.next;
    }
    while(!sta.empty()){
      newI.add(sta.pop());
    }
  }
  return newI;
}

十二、

输入一个链表,输出该链表中倒数第k个结点。

思路:
在getLength()方法中得到链表的长度,在主函数中将链表移动size-k次

解答(大佬):

/*
public class ListNode {
  int val;
  ListNode next = null;

  ListNode(int val) {
    this.val = val;
  }
}*/

public class Solution {
  public ListNode FindKthToTail(ListNode head,int k) {
    int size=getLength(head);
    if(size==k)
      return head;
    else if(size<k)
      return null;
    for(int i=0;i<size-k;i++){
      head=head.next;
    }
    return head;
  }
  public static int getLength(ListNode head){
    int length=1;
    if(head==null)
      return 0;
    while(head.next!=null){
      length=length+1;
      head=head.next;
    }
    return length;
  }
}

最佳代码:Java代码,通过校验。代码思路如下:两个指针,先让第一个指针和第二个指针都指向头结点,然后再让第一个指正走(k-1)步,到达第k个节点。然后两个指针同时往后移动,当第一个结点到达末尾的时候,第二个结点所在位置就是倒数第k个节点了。
/*
public class ListNode {
  int val;
  ListNode next = null;

  ListNode(int val) {
    this.val = val;
  }
}*/
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;
  }
}

十三、

输入一个有符号整数,输出该整数的反转值。
思路:
利用StringBuffer的reverse()方法,反转其值

解答:
public static int change(int x){
  boolean flag =true;
  StringBuffer sb;
  if(x>=0){
    String str = String.valueOf(x);
    sb = new StringBuffer(str);
    sb.reverse();
  }else {
    flag=false;
    x=-x;
    String str = String.valueOf(x);
    sb = new StringBuffer(str);
    sb.reverse();
  }
  return !flag?(-(Integer.valueOf(sb.toString()))):Integer.valueOf(sb.toString());
}

十四、

若干个硬币,求和为N元的最小硬币数(动态规划)
思路:
若硬币为{1,2,5}元,要11元的解集,那么有5+5+1,只需要三个硬币数。
若我们需要0元,那么只要0个硬币,若要1元,需要1个硬币。
若为2元,那么需要1个两元硬币,或者两个1元硬币,但是最小硬币数,所以只需要一个2元硬币就够了。
若为3元,需要1+2,两个硬币。
若为4元,需要2+2,需要两个硬币.....
得出结论,f(n)=f(n-x)+1
n表示n元,f(n)表示n元需要的最小硬币数,x表示我们有的硬币大小,如1,2,5元
f(n)=f(n-x)+1,可解读为:n元的最小硬币数=(n-x)元的硬币+1
若n=11,假设全部用1元,那么需要11个1元硬币,但是最小硬币数应为5+5+1元,3个硬币,
那么有f(11)=f(11-5)+1,
f(6)=f(6-5)+1,
f(1)=f(1-1)+1,
f(0)=0.
所以往上推,有f(0)=0,f(1)=1,f(6)=2,f(11)=3
但是,需要满足前提条件
1.n>x,N元要大于取出的硬币数值,如,N=3,那么我们就不能取5元,因为5>3
2.f(n-x)+1要小于原来的f(n),否则需要的硬币数反而变多了
4元,假设需要4个1元硬币,那么我们就不取1元的,直接取1元后面的2元,那么有
f(4)=f(4-2)+1=f(2)+1
f(2)=f(2-2)+1=1
所以f(4)=2
解答:
public static void main(String[] args) throws Exception {
  int[] coin={1,2,5};
  int sum=11; //sum表示N元
  int[] use = new int[sum+1];
  use[0]=0;
  for(int i=1;i<=sum;i++){
    use[i]=i; //use=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
  }
  for(int i=1;i<=sum;i++){
    for(int j=0;j<3;j++){
      if(i>=coin[j]&&use[i]>(use[i-coin[j]]+1)){
        use[i] = use[i- coin[j] ] + 1;
      }
    }
  }
  System.out.println(use[sum]);
}

转载于:https://www.cnblogs.com/zhuii/p/9940290.html

算法编程-不定时更新相关推荐

  1. 排序算法(不定时更新~)

    插入排序: /*** 插入排序* 初始时,拿第二个和第一个比较,如果第二个小于第一个,两个交换* 当进行到第N次时,前面的N-1个顺序应该是正确的* 拿第N个和前面的N-1个数比较,如果第M个小于N, ...

  2. [Android Traffic] 调整定时更新的频率(C2DM与退避算法)

    转载自: http://blog.csdn.net/kesenhoo/article/details/7395253 Minimizing the Effect of Regular Updates[ ...

  3. 【面试锦囊】14种模式搞定面试算法编程题(1-7)

    面试锦囊之知识整理系列 面试锦囊系列一直有收到大家的反馈,包括后台内推成功的消息.朋友的同事从创业小公司成功跳到huawei等等,非常高兴小破号的这些整理分享能够真正地帮助到大家,以后也会继续.为了更 ...

  4. 【面试锦囊】14种模式搞定面试算法编程题(8-14)

    面试锦囊之知识整理系列 面试锦囊系列一直有收到大家的反馈,包括后台内推成功的消息.朋友的同事从创业小公司成功跳到huawei等等,非常高兴小破号的这些整理分享能够真正地帮助到大家,以后也会继续.为了更 ...

  5. 14种模式解决面试算法编程题(PART I)

    万万没想到,暑假还没开始,有些公司的秋招提前批已经来了-很慌-数据结构和算法题可以说是秋招笔试面试必考的内容,如果你还不够熟练(just like me),那就要从现在开始疯狂刷题了啊朋友们. 附上我 ...

  6. 2022程序员都推荐的算法编程课程终于来了!新手从入门到面试考点全覆盖,学到就是赚到!...

    还在自学算法&编程像个无头苍蝇一样没有头绪?看完这篇文章帮你解决问题! (❗干货警告:文末附2022大厂最新面试真题~) 程序员作为一个高薪行业已经明显出现"内卷"情况了! ...

  7. AirSim学习和踩坑记录(不定时更新)

    版权声明:本文为博主原创文章,遵循Creative Commons - Attribution-ShareAlike 4.0 International - CC BY-SA 4.0版权协议,转载请附 ...

  8. 【原创】强化学习笔记|从零开始学习PPO算法编程(pytorch版本)

    从零开始学习PPO算法编程(pytorch版本)_melody_cjw的博客-CSDN博客_ppo算法 pytorch 从零开始学习PPO算法编程(pytorch版本)(二)_melody_cjw的博 ...

  9. 算法编程Algos Programming

    算法编程Algos Programming 不同算法的集合,用于编程比赛,如ACM ICPC. 算法按主题划分.大多数算法都可以从文件中按原样运行.每种算法都有一个参考问题,并对其时间和空间复杂度作了 ...

  10. apue第四章习题的一些拙见(不定时更新)

    写在前面:最近要期末考试,看来真的是要不定时更新啦XD apue4.1: 由于在这里lstat是不跟随符号文件的,而stat是跟随符号文件的,这样一来,如果使用stat,而不使用lstat那么就无法观 ...

最新文章

  1. 小鱼便签_同样是写便签,这样更酷
  2. HashMap如何在Java中工作
  3. 基于JAVA+SpringMVC+Mybatis+MYSQL的图书馆预约占座管理系统
  4. Python:使用threading模块实现多线程编程三[threading.Thread类的重要函数]
  5. fstatfs/statfs详解
  6. 无线网卡802.11n、 Intel 5100 AGN
  7. Atitit zip压缩过滤器 的模块功能语实现attilax总结 1.1. 一般可以使用webserver自带的实现,。如果实现的不好或者不好配置的,或者需要精细化控制的,可以自己使用过滤器实现。
  8. 劢领AT| 五分钟,零基础玩转Wing中国电信物联网开放平台
  9. excel快速便捷批量填充
  10. 重装Win7系统步骤和详细教程
  11. 在视图列中显示文档所有读者和作者
  12. H5怎么制作?快来看这个H5制作平台的案例你可能就明白了
  13. linux slub分配器,Vi Linux内存 之 Slub分配器(六)
  14. 《登黄山偶感》艺术品赏
  15. QA之道知多少(一) 初出茅庐
  16. 美拍作者页视频的保存的方法
  17. 新浪云sae怎么上传php代码,如何在新浪SAE中上传文件和在线修改模板
  18. sklearn数据降维之字典学习
  19. 数据库隔离级别的理解
  20. MT7688详细芯片资料下载  MT7688规格说明简介

热门文章

  1. wpf silverlight的Behavior
  2. R_空间插值_必知必会(二)
  3. 用data.table语句批量处理变量
  4. visual studio 中将选中代码相同的代码的颜色设置,修改高亮颜色
  5. 适合程序员演讲的定场诗
  6. Kia#39;s Calculation(贪心)
  7. “敏捷开发”怎么就“敏捷”了
  8. 1225 八数码难题
  9. Java面向对象的继承
  10. Cocos数据篇[3.4](3) ——XML数据操作