华为机试_简单题目

更多的是交流和自己做笔记用

HJ35蛇形矩阵

题目如下:
在这里插入图片描述
首先可以观察规律暴力输出:
这是我第一次写的,比较没有逻辑,因为我个人会有点逃避性使用多维数组。

package OnlineTest.easy;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Scanner;

public class HJ35 {
    public static void main(String[] args) throws IOException {
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        //获取行数
        int line = Integer.parseInt(bf.readLine());
        //
        int first = 1;
        int cal=first;
        int lineNext;
        for (int i = 0; i < line; i++) {//输出第i行
            cal = cal + i;//输出第i行的第一个数
            lineNext=cal;
            System.out.print(cal+" ");
            for (int j = 1; j < line - i; j++) {//输出第i行除了第一个数
                lineNext=lineNext+(i+1)+j;
                System.out.print(lineNext+ " ");
            }
            System.out.println();//断行;
        }
    }
}

这是我又试着用多维数组写出来的。
int [] [] a 就把前一个[]想成是有多少行,后一个就是针对第i行而言,这个一行有多少个元素,有点这个意思:
在这里插入图片描述
(写完感觉也差不多)

package OnlineTest.easy;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Calendar;
import java.util.Scanner;

public class HJ35 {
    public static void main(String[] args) throws IOException {
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        //获取行数
        int line = Integer.parseInt(bf.readLine());
        int[][] marix = new int[line][];

        int o=1;
        int ColNextNumber=o;
        int RowNextNumber;

        for (int i = 0; i < line; i++) {
            marix[i] = new int[line - i];
            marix[i][0] = ColNextNumber;
            RowNextNumber=ColNextNumber;
            for (int j = 1; j < marix[i].length; j++) {
                RowNextNumber=RowNextNumber+(i+1)+j;
                marix[i][j] =RowNextNumber;
            }
            //下一行的
            ColNextNumber = ColNextNumber + (i + 1);
        }
        for (int[] row : marix) {
            for (int cal : row) {
                System.out.print(cal+" ");
            }
            System.out.println();
        }

    }
}

HJ53 杨辉三角的变形

在这里插入图片描述
在这里插入图片描述

可惜用数组会发生heap溢出错误,如下。因此需要更改算法

package OnlineTest.easy;

import java.util.Scanner;

public class HJ53 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            //获取行数
            int lines = sc.nextInt();
            //建立一半的列
            int col =lines;
            //构建一个的矩阵
            int[][] m = new int[lines][col];
            //填充第一行
            for (int i = 0; i < m[0].length; i++) {
                m[0][i] = 0;
            }
            m[0][col-1]=1;
            //从第二行起,遍历每一行
            for (int i = 1; i < lines; i++) {
                //不是最后一行
                if (i < lines - 1) {
                    m[i][0]=0;
                    m[i][1] = 1;
                }
                //是最后一行
                else {
                    m[i][0]=1;
                }
                //填充该行后面的数字
                for (int k = 1; k <=col - 2; k++) {
                        m[i][k] = m[i - 1][k - 1] + m[i - 1][k] + m[i - 1][k + 1];
                }
                m[i][col-1]=m[i-1][col-2]+m[i-1][col-2]+m[i-1][col-1];
            }
            //矩阵构造完毕;可以输出检查
/*            for (int[] x : m) {
                for (int y : x) {
                    System.out.print(y+" ");
                }
                System.out.println();
            }*/


            //输出第一个偶数出现的位置
            for (int i = 0; i < col; i++) {
                if (m[lines-1][i] % 2 == 0) {
                    System.out.print(i+1);
                    break;
                }
                if (i == col- 1) {
                    System.out.println(-1);
                }

            }

        }
    }
}

放苹果问题(递归)

m个苹果放进n个盘子,m,n可以为0,例如4个苹果放进3个盘子,{1,2,1}和{2,1,1}是一种方法。

分析:
设f(m,n)为将m个苹果放到n个盘子里面的放法总数,m,n>=0;
分为两种情况:至少有一个盘子空着+所有盘子都不空着
(1)至少有一个盘子空,可以每次减少一个盘子来递归,因为,没减少一个空盘子,不影响放法的增减。也就是f(m,n-1)
(2)所有盘子都不空着,可以每次减少一层来递归。因为,每个盘子都有苹果的话,相当于这一层的底数都是1,减少这一层基数后,不影响放法的增减。也就是f(m-n,n);

因此,递归表达式为: f(m,n)=f(m,n-1)+f(m-n,n)
结束条件:所有至少有一个盘子为空的情况会递归到所有盘子都不空着的情况;所有盘子都不空着的情况会递归到至少有一个不会为空的清空,循环往复,会递归到,只有一个盘子一个苹果,也就是(1,1),再递归就是只有0个苹果,一个盘子,因此结束条件:
f(0,0)=1 ;
f(0,n)=1;
f(1,1)=1;

package OnlineTest.easy;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class HJ61 {

    /*分析:
    设f(m,n)为将m个苹果放到n个盘子里面的放法总数,m,n>=0;
    分为两种情况:至少有一个盘子空着+所有盘子都不空着
        (1)至少有一个盘子空,可以每次减少一个盘子来递归,因为,没减少一个空盘子,不影响放法的增减。也就是f(m,n-1)
        (2)所有盘子都不空着,可以每次减少一层来递归。因为,每个盘子都有苹果的话,相当于这一层的底数都是1,减少这一层基数后,不影响放法的增减。也就是f(m-n,n);

    因此,递归表达式为:
        f(m,n)=f(m,n-1)+f(m-n,n)*/

    public static void main(String[] args)throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String[] s = br.readLine().split(" ");
        int apple, plate;
        apple = Integer.parseInt(s[0]);
        plate = Integer.parseInt(s[1]);
        System.out.println(count(apple,plate));
    }

    public static int count(int m, int n) {
        if (m < 0||n<=0) {
            return 0;
        } else if (m ==1 || n == 1|| m==0) {//m=0的时候也算一种方法!
            return 1;
        }
        else {
            return count(m, n - 1) + count(m - n, n);
        }
    }
}

难点就是找递归表达式以及终止条件,多思考多练。

表示数字

这题就是,怎么说,会正则的话就会很简单…
在这里插入图片描述
还是先附上自己写的代码,然后看了看大佬的代码,补了一下正则表达式;

package OnlineTest.easy;

import java.util.Scanner;

public class HJ96 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            StringBuilder s = new StringBuilder(sc.nextLine());
            int length = s.length();
            int a,b;
            a=0;
            for (int i = 0; i < length;i=a) {
                char c = s.charAt(a);
                //如果是数字
                if (Character.isDigit(c)) {
                    //插入数字
                    //注意,inser(offest,char)中的offset指的是第几个,不是下标
                    s.insert(a, '*');
                    //a仍指向第一个数字
                    a = a + 1;
                    //b和a指向一个数字
                    b = a;
                    //后指针遍历到文末
                    //总长度已经增加1个了
                    length++;
                    while (b < length && Character.isDigit(s.charAt(b))) {
                        b++;
                        continue;
                    }
                    s.insert(b, '*');
                    length += 1;
                    a = b + 2;
                } else {
                    a++;
                }
            }
            System.out.println(s);
        }
    }
}

这是正则

package OnlineTest.easy;

import java.util.Scanner;

public class HJ96 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            String s = sc.nextLine();
            //添加一个加号,才能把连续的数字看成是一体的
            String re = "([0-9]+)";
            //$1表示正则表达式中第一个()表达式中匹配的内容
            System.out.println(s.replaceAll(re, "*$1*"));
        }
    }
}

统计字符(涉及Comparator方法)

题目不难,主要下个用比较器来做做看
在这里插入图片描述
在这里插入图片描述

package OnlineTest.easy;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

public class HJ102 {
    public static void main(String[] args) throws IOException {
        /*思路:
        * (1)集合(字母,次数)
        * (2)compartor比较器 */

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringBuilder sb = new StringBuilder(br.readLine());
        HashMap<String, Integer> hm = new HashMap<>();

        for (int i = 0; i < sb.length(); i++) {
            String s = String.valueOf(sb.charAt(i));
            if (hm.containsKey(s)) {
                int t = hm.get(s);
                t++;
                hm.put(s, t);
            }
            else {
                hm.put(s, 1);
            }
        }

        List<stringO> list = new LinkedList<>();
        hm.forEach((k,v)->{
            list.add(new stringO(k, v));
        });

        Collections.sort(list, new stringOComparator());

        list.forEach(o->{
            System.out.print(o.s);
        });
    }
}
class stringO{
    int times;
    String s;

    public stringO(String s,int times) {
        this.times = times;
        this.s = s;
    }

    @Override
    public String toString() {
        return "stringO{" +
                "times=" + times +
                ", s='" + s + '\'' +
                '}';
    }
}

class stringOComparator implements Comparator {
    @Override
    public int compare(Object obj1, Object obj2) {//参数要一致,才算
        stringO o1 = (stringO) obj1;
        stringO o2 = (stringO) obj2;
        //次数大的排在前面
        if (o1.times > o2.times) {
            return -1;
        } else if (o1.times < o2.times) {
            return 1;
        } else {
            //比较ASCii
            char c1 = o1.s.charAt(0);
            char c2 = o2.s.charAt(0);
            if (c1 > c2) {
                return 1;
            } else if (c1 < c2) {
                return -1;
            } else {
                return 0;
            }
        }
    }
}

输出单向链表中倒数第k个结点

考察:用java实现单链表创建

package OnlineTest.easy;

import java.util.Scanner;

public class HJ51 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            int length = sc.nextInt();
            Node head = new Node(-1);//定义头节点
            Node p=head;//p指针指向head
            for (int i = 0; i < length; i++) {
                int value = sc.nextInt();
                p.next = new Node(value);
                p = p.next;//移动p指针
            }
            int k = sc.nextInt();
            for (int i = 0; i < length - k + 1; i++) {
                head=head.next;
            }
            System.out.println(head.data);
        }
    }

}

class Node {
    /*定义节点*/
    int data;
    Node next;

    public Node(int data) {
        this.data = data;
        this.next = null;
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值