华为2020秋招笔试2020.9.9全A

笔试记录

晚上刚写完的笔试,在这边记录一下,总的今天的笔试还是比较简单的,

题1

大概回忆:
题目大意可以类比字符串匹配。刚开始用的暴力遍历去解的,结果不出意料,超时,过了90%样例,尝试剪枝,于是过了80%,最后参考KMP算法进行书写,AC。KMP不大记得了,现推了一下,可以找找其他地方说明看一下。
暴力解法

import java.util.*;
public class Main {
    public static void main(String[] args) {
        Scanner scanner=new Scanner(System.in);
        int k=scanner.nextInt();
        int a=0,b=0;
        int[] A=new int[k];int[] B=new int[k];
        int[] perfect=new int[k];
        for (int i=0;i<k;i++){
            A[i]=scanner.nextInt();
        }
        for (int i=0;i<k;i++){
            B[i]=scanner.nextInt();
            perfect[i]=A[i]*10+B[i];
        }

        int n=scanner.nextInt();
        int[] next=new int[n];
        int[] C=new int[n];int[] D=new int[n];
        int[] cur=new int[n];
        next[0]=-1;
        for (int i=0;i<n;i++){
            C[i]=scanner.nextInt();
        }
        int temp;
        for (int i=0;i<n;i++){
            D[i]=scanner.nextInt();
            cur[i]=C[i]*10+D[i];
            temp=i-1;
            if(i!=0){
                while(temp!=-1&&cur[i]!=cur[next[temp]+1]){
                    temp=next[temp];
                }
                if(temp==-1){
                    next[i]=temp;
                }else
                    next[i]=next[temp]+1;
            }
        }
        int pos=0;
        for(int i=0;i<n;i++){
            if(cur[i]==perfect[0]){
                int j=0;
                for(;j<perfect.length;j++){
                    if(i+j>=n||cur[i+j]!=perfect[j]){
                        i=i+(j-next[j]);
                        break;
                    }
                }
                if(j==perfect.length){
                    pos=i+1;
                    break;
                }
            }
        }
        System.out.println(pos);
    }
}
//kmp版本
import java.util.*;
public class Main {
    public static void main(String[] args) {
        Scanner scanner=new Scanner(System.in);
        int k=scanner.nextInt();
        int a=0,b=0;
        int temp;
        int[] A=new int[k];int[] B=new int[k];
        int[] perfect=new int[k];
        for (int i=0;i<k;i++){
            A[i]=scanner.nextInt();
        }
        for (int i=0;i<k;i++){
            B[i]=scanner.nextInt();
            perfect[i]=A[i]*10+B[i];
        }

        int n=scanner.nextInt();
        int[] next=new int[n];
        int[] C=new int[n];int[] D=new int[n];
        int[] cur=new int[n];
        next[0]=0;
        for (int i=0;i<n;i++){
            C[i]=scanner.nextInt();
            temp=i-1;
            if(i!=0){
                while(temp!=0&&cur[i]!=cur[next[temp]+1]){
                    temp=next[temp];
                }
                if(temp==0){
                    next[i]=temp;
                }else
                    next[i]=next[temp]+1;
            }
        }
        for (int i=0;i<n;i++){
            D[i]=scanner.nextInt();
            cur[i]=C[i]*10+D[i];
        }
        int pos=0;
        int perpos=0;
        int curpos=0;
        while(perpos<perfect.length&&curpos<cur.length){
//            System.out.println("perpos:"+perpos+"curpos:"+curpos);
            if(perfect[perpos]==cur[curpos]){
                perpos++;
                curpos++;
            }
            else if(perpos==0){
                curpos++;
            }
            else{
                perpos=next[perpos];
            }
            if(perpos==perfect.length)break;
        }
        if(perpos==perfect.length){
            pos=curpos-perpos+1;
        }
        System.out.println(pos);
    }
}

题二

在二维数组中,可以从大的那个数开始周围小的地方走(上下左右四个方向),输出这样子最多可以走多少步。思路:记录下可能成为最佳起点的位置,然后直接逐个dfs。

import java.util.*;
public class Main{
    static int cntmax=0;
    private static boolean inrange(int i,int j,int m,int n){
        return i>=0&&i<m&&j>=0&&j<n;
    }
    private static boolean istop(int i,int j,int[][] map){
        int m=map.length,n=map[0].length;
        if(inrange(i-1,j,m,n)){
            if(map[i-1][j]>map[i][j]){
                return false;
            }
        }
        if(inrange(i+1,j,m,n)){
            if(map[i+1][j]>map[i][j]){
                return false;
            }
        }
        if(inrange(i,j-1,m,n)){
            if(map[i][j-1]>map[i][j]){
                return false;
            }
        }
        if(inrange(i,j+1,m,n)){
            if(map[i][j+1]>map[i][j]){
                return false;
            }
        }
        return true;
    }

    public static void main(String[] args) {
        Scanner scanner=new Scanner(System.in);
        int m=scanner.nextInt();
        int n=scanner.nextInt();
        int[][] map=new int[m][n];
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                map[i][j]=scanner.nextInt();
            }
        }
        ArrayList<ArrayList> list=new ArrayList<>();
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                if(istop(i,j,map)){
                    ArrayList<Integer> integers=new ArrayList<>();
                    integers.add(i);
                    integers.add(j);
                    list.add(integers);
                }
            }
        }
        for (ArrayList<Integer> a: list) {
            int sl=a.get(0);
            int sr=a.get(1);
            dfs(sl,sr,1,map);
        }
        System.out.println(cntmax);
    }
    private static void dfs(int i,int j,int cnt,int[][] map){
        cntmax=cntmax>cnt?cntmax:cnt;

        int m=map.length,n=map[0].length;
        if(inrange(i-1,j,m,n)&&map[i-1][j]<map[i][j]){
            dfs(i-1,j,cnt+1,map);
        }
        if(inrange(i+1,j,m,n)&&map[i+1][j]<map[i][j]){
            dfs(i+1,j,cnt+1,map);
        }
        if(inrange(i,j-1,m,n)&&map[i][j-1]<map[i][j]){
            dfs(i,j-1,cnt+1,map);
        }
        if(inrange(i,j+1,m,n)&&map[i][j+1]<map[i][j]){
            dfs(i,j+1,cnt+1,map);
        }
    }
}

题三

给定一棵树,可以从任意一个节点开始往叶子节点走,可以在任何一个地方停下,输出所有路径中的最大值,思路:直接遍历

import java.util.*;
public class Main{
    static int num=0;
    static int maxv=0;
    static class TreeNode{
        int id,weight,left,right;
        TreeNode(){}
        TreeNode(int id,int weight){this.id=id;this.weight=weight;left=-1;right=-1;}
    }

    private static void dfs(int i,TreeNode[] treeNodes){
        num^=treeNodes[i].weight;
        maxv=maxv>num?maxv:num;
        if(treeNodes[i].left!=-2){
            dfs(treeNodes[i].left,treeNodes);
        }
        if(treeNodes[i].right!=-2){
            dfs(treeNodes[i].right,treeNodes);
        }
        num^=treeNodes[i].weight;
    }
    public static void main(String[] args) {
        Scanner scanner=new Scanner(System.in);
        int nums=scanner.nextInt();
        TreeNode[] treeNodes=new TreeNode[nums];
        int id=0;
        for(int i=0;i<nums;i++){
            id=scanner.nextInt()-1;
            treeNodes[id]=new TreeNode();
            treeNodes[id].id=id;
            treeNodes[id].weight=scanner.nextInt();
            treeNodes[id].left=scanner.nextInt()-1;
            treeNodes[id].right=scanner.nextInt()-1;
        }
        for(int i=0;i<treeNodes.length;i++){
            dfs(i,treeNodes);
        }
        System.out.println(maxv);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值