5.30 算法面试题解

Java面试-5道算法

笔试题还是遇到了算法题,我对于做答题从来不慌,就是算法题总是不够稳。今天是五道算法题,我一道一道的来讲解一下。题目由我个人简单描述

第一题:

丑数:判断一个数是否是一个丑数。丑数是指只有质因数2,3,5的正整数,包括自然数1。是丑数返回1,不是丑数返回0。

解析

我的思路是通过把这个数依次做判断,如果能被2整除,那就/2,如果能被3整除,那就/3,如果能被5整除,那就/5,如果都不行就不是丑数;把这个判断做循环,如果最后剩下来1,那么就是丑数

public int isUglyNumber(int num){
   if(num<1)return 0;
   if(num<7)return 1;
   while(true){
      if(num==1)return 1;
      else{
       if(num%2==0) num/=2;
        else if(num%3==0) num/=3;
        else if(num%5==0) num/=5;
        else return 0;
      }
   }
}

网上搜了一下,其实可以直接while循环遍历,判断最后是不是剩下1

public boolean isUgly(int num) 
    {
           if(num<=0) return false;
           
           while(num%2==0) num/=2;
           while(num%3==0) num/=3;
           while(num%5==0) num/=5;
           
           return (num==1);
    }
第二题:

卡牌游戏:小三给小舞n张牌,分别是0到n-1,把他们按顺序从0-n-1排成环形,然后从0开始走,每三步抽掉一张牌,问最后留下哪一张卡牌,返回他的数字。

解析

我首先想到先用队列,发现放值取值复杂,单纯数组晒选应该可以,但都不是正统思路,其实他就是一个约瑟夫环的问题`,我用的是一个个计数,循序到0时重新开始从头遍历,如果去掉一张牌总共的牌数减一。直到只剩下一个人。

public static int josephus(int n, int m) {
        //n个人,  0 1 2..n-1
         int[] people = new int[n];
        //人的索引
         int index = -1;
        //报数记录,  1 2 3..m
         int count = 0;
        //剩余人数  初始值为n
         int remain = n;

        //为了找到最后一个幸存者的位置,假设所有人都会被杀
        while (remain > 0) {   
             index++;         //找到报数的人
             if (index == n) {  //所有人遍历一圈后从头遍历
                   index = 0;
              }
              if (people[index] == -1) { //如果当前的人被杀  跳过
                  continue;
              }

              count++;  //报数
              if (count == m) {  
                  people[index] = -1;  //报数到m后杀人
                  count = 0;  //报数重置
                  remain--;   //剩余人数递减
               }
        }
        return index;
}

上面这种计数过程比较浪费空间,用LinkedList双向链表实现思路更加清晰。

public static int cycle(int n){
  List<Integer> dataList=new LinkedList<>();
  for(int i=0;i<n;i++){
     dataList.add(i+1);
 }
  int index=-1;
  while(dataList.size()>1){
    index=(index+3)%dataList.size();
    dataList.remove(index--);
}
 return dataList.get(0);
}
第三题:

进制转换:将一个进制为N的字符串转换成另一个进制为M的字符串

   public static String changeRadix(String num,int N,int M){
        Long i=Long.valueOf(num,N);
        if(i<M){
            if(i>9) return (char)(i+55)+"";
            else return i+"";
        }
        return changeRadix(i/M+"",10,M)+changeRadix(i%M+"",10 ,M );
    }
第四题:

Z字排列:将一个字符串按照指定行数line,像“N”字型排列,然后输入正常从左往右逐行读的字符串,空字符不读。

解析:

道题没什么可说的,不需要什么数据结构与算法的知识。给定一个字符串,换个花样输出。题目中所谓的"Z"字形变换,无非就包含两种操作,直接按题目要求模拟,先竖着往下读,然后斜上读,一直将字符串读完为止。

  public String convert(String s, int numRows) {
        if (numRows == 1) {
            return s;
        }
        StringBuilder[] sbs = new StringBuilder[numRows];
        for (int i = 0; i < numRows; i++) {
            sbs[i] = new StringBuilder();
        }
        int index = 0;
        while (index < s.length()) {
            // "竖下"读取
            for (int i = 0; i < numRows && index < s.length(); i++) {  // 这里加index < s.length() 是防止在做"竖下"操作的时候字符串读完了,下面同理
                sbs[i].append(s.charAt(index));
                index++;
            }
            // "斜上"读取,从下往上读,最后一行和第一行是算在"竖下"读取中的,所以只存中间numRows - 2行
            for (int i = numRows - 2; i > 0 && index < s.length(); i--) {
                sbs[i].append(s.charAt(index));
                index++;
            }
        }
        // 将后面numRows-1行都拼接到第一行
        for (int i = 1; i < numRows; i++) {
            sbs[0].append(sbs[i]);
        }
        return sbs[0].toString();
    }
第五题:

青蛙跳:从x轴0的位置开始跳,第一次跳一步,下一步比第一步多一步,每一步可以往正方向也可以往反方向,问你要几步到达给定目的地target。

解析:

这道题没做出来,之前也有一个类似的问题,他说可以跳坐标的任意倍数,问最短几步到达target。我不知道是按照递归还是什么思路,单个模拟也没有思路。现在还没想到怎么做,尖刀班的学生可以指点我一下。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值