牛客网刷题 第一轮

1.1

public class Solution {
    public boolean Find(int target, int [][] array) {
        int a = array.length - 1;
        int b = array[1].length - 1;
        int i = 0;
        while(a >= 0 && i <= b){
           if(array[a][i] == target){
               return true;
           }
            else if(array[a][i] < target){
               i ++;
           }
            else if(array[a][i] > target){
               a --;
           }
    }
        return false;
    }
}
  • 结果:

不通过
您的代码已保存
答案错误:您提交的程序没有通过所有的测试用例
case通过率为41.18%

用例:
16,[[]]

对应输出应该为:

false

你的输出为:

java.lang.ArrayIndexOutOfBoundsException: 1

1.2 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。

public class Solution {
    public boolean VerifySquenceOfBST(int [] sequence) {
        if(sequence.length == 0){
            return false;
        }else if(sequence.length == 1){
            return true;
        }
        else{
            return isLastOrder(sequence,0,sequence.length-1);
        }
    }
     public boolean isLastOrder(int[] sequence, int start, int end){
        if (start == end) {
            return true;
        }
        int i = start;
        while (i <= end && sequence[i] < sequence[end]) {
            i++;
        }
        i -- ;
        int j = end;
        while (j >= start && sequence[j] >= sequence[end]) {
            j--;
        }
        j ++;
        if (i >= j) {
            return false;
        }
        if(i + 1 != j){
            return false;
        }
         if(i == -1 || i == end - 1){
             return isLastOrder(sequence,start,end - 1);
         }
        return isLastOrder(sequence, start, i) && isLastOrder(sequence, j, end - 1);
    }
} 

1.3 复杂链表遍历

  • 思路:
  • 1.在原来链表的基础上,加入新的节点,新的节点在插入旧的节点后面
  • 2.将原来节点的随机指针复制给新节点的随机指针
  • 3.将两个链表分离,返回新链表的头结点

1.4 二叉排序树转变为双向排序链表

  • 思路:使用中序遍历树的方法即可

1.5 全排列

引用牛客网一个老哥的图:
在这里插入图片描述注意点:需要将刚开始的数组保留一份,不然下次就是在上一次变化的基础上变化,就会出错。

1.6 输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4。

  • 思路:将数组的前k个数进行排序,然后从第k+1个数开始与前k个数进行比较,使用插入排序的思路,保证前k个数始终是遍历过得数中最小的。
import java.util.ArrayList;

public class Solution {
     public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) {
        ArrayList<Integer> objects = new ArrayList<Integer>();
         if(k>input.length || k == 0){
             return objects;
         }
        sort(input,k);
        if(k + 1 < input.length) {
            for (int j = k; j < input.length; j++) {
                insert(input, k - 1, j);
            }
        }
        for (int i = 0; i < k; i++) {
            objects.add(input[i]);
        }
       return objects;
    }
    public static void sort(int[] arrray, int length){
        for (int i =0;i < length; i ++){
            for(int j = 0; j<length -i-1;j++){
                if(arrray[j + 1] < arrray[i]){
                    int mid = 0;
                    mid = arrray[j + 1];
                    arrray[j + 1 ] = arrray[j];
                    arrray[j] = mid;
                }
            }
        }
    }
    public static void insert(int[] array,int end, int index){
           if(array[index] > array[end]){
               return;
           }
            int flag = end;
            while (array[index] < array[flag] && flag > 0){
                flag--;
            }
                int mid = array[index];
                for(int j=end;j>=flag;j--){
                    array[j + 1] = array[j];
                }
                array[flag] = mid;
            }
}

1.9 求数组的最大连续子序列的和

* 从第一个数开始计算,找最大值的规律
*  找以当前值为结尾的最大值。
此处引用牛客上大佬的思路:

使用动态规划
F(i):以array[i]为末尾元素的子数组的和的最大值,子数组的元素的相对位置不变
F(i)=max(F(i-1)+array[i] , array[i])
res:所有子数组的和的最大值
res=max(res,F(i))
如数组[6, -3, -2, 7, -15, 1, 2, 2]
初始状态:
F(0)=6
res=6
i=1:
F(1)=max(F(0)-3,-3)=max(6-3,3)=3
res=max(F(1),res)=max(3,6)=6
i=2:
F(2)=max(F(1)-2,-2)=max(3-2,-2)=1
res=max(F(2),res)=max(1,6)=6
i=3:
F(3)=max(F(2)+7,7)=max(1+7,7)=8
res=max(F(2),res)=max(8,6)=8
i=4:
F(4)=max(F(3)-15,-15)=max(8-15,-15)=-7
res=max(F(4),res)=max(-7,8)=8
以此类推
最终res的值为8

public class Max {
    public static void main(String[] args) {
        int array[] = new int[]{1,-3,2,-4,-3,-2,-4};
        System.out.println(findmax(array));
    }
    public static int findmax(int[] array){
         int res = array[0];
         int max = array[0];
        for (int i = 1; i < array.length; i++) {
            max = Math.max(max + array[i], array[i]);
            res = Math.max(max,res);
        }
        return res;
    }
}

1.10 输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。

* 解题思路:
 * 先将整型数组转换成String数组,然后将String数组排序,最后将排好序的字符串数组拼接出来。关键就是制定排序规则。
 * 排序规则如下:
 * 若ab > ba 则 a > b,
 * 若ab < ba 则 a < b,
 * 若ab = ba 则 a = b;
 * 解释说明:
 * 比如 "3" < "31"但是 "331" > "313",所以要将二者拼接起来进行比较
public String PrintMinNumber(int [] numbers) {
        if(numbers == null || numbers.length == 0) return "";
        int len = numbers.length;
        String[] str = new String[len];
        StringBuilder sb = new StringBuilder();
        for(int i = 0; i < len; i++){
            str[i] = String.valueOf(numbers[i]);
        }
        Arrays.sort(str,new Comparator<String>(){
            @Override
            public int compare(String s1, String s2) {
                String c1 = s1 + s2;
                String c2 = s2 + s1;
                return c1.compareTo(c2);
            }
        });
        for(int i = 0; i < len; i++){
            sb.append(str[i]);
        }
        return sb.toString();
    }

1.11 把只包含质因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含质因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。

解题思路来源:牛客网上的大佬

首先从丑数的定义我们知道,一个丑数的因子只有2,3,5,那么丑数p = 2 ^ x * 3 ^ y * 5 ^ z,换句话说一个丑数一定由另一个丑数乘以2或者乘以3或者乘以5得到,那么我们从1开始乘以2,3,5,就得到2,3,5三个丑数,在从这三个丑数出发乘以2,3,5就得到4,6,10,6,9,15,10,15,25九个丑数,我们发现这种方***得到重复的丑数,而且我们题目要求第N个丑数,这样的方法得到的丑数也是无序的。那么我们可以维护三个队列:
(1)丑数数组: 1
乘以2的队列:2
乘以3的队列:3
乘以5的队列:5
选择三个队列头最小的数2加入丑数数组,同时将该最小的数乘以2,3,5放入三个队列;
(2)丑数数组:1,2
乘以2的队列:4
乘以3的队列:3,6
乘以5的队列:5,10
选择三个队列头最小的数3加入丑数数组,同时将该最小的数乘以2,3,5放入三个队列;
(3)丑数数组:1,2,3
乘以2的队列:4,6
乘以3的队列:6,9
乘以5的队列:5,10,15
选择三个队列头里最小的数4加入丑数数组,同时将该最小的数乘以2,3,5放入三个队列;
(4)丑数数组:1,2,3,4
乘以2的队列:6,8
乘以3的队列:6,9,12
乘以5的队列:5,10,15,20
选择三个队列头里最小的数5加入丑数数组,同时将该最小的数乘以2,3,5放入三个队列;
(5)丑数数组:1,2,3,4,5
乘以2的队列:6,8,10,
乘以3的队列:6,9,12,15
乘以5的队列:10,15,20,25
选择三个队列头里最小的数6加入丑数数组,但我们发现,有两个队列头都为6,所以我们弹出两个队列头,同时将12,18,30放入三个队列;
……………………

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值