Leetcode面T16(1-9)树,掌握了这些Android高级工程师必备知识

这篇博客介绍了几个在LeetCode上的算法题目,包括阶乘尾数、最小差、最大数值、整数的英语表示以及生存人数等,这些都是Android高级工程师应该掌握的知识。题目涵盖数据结构和算法,如阶乘中的零个数计算、数组操作和整数表示转换。文章提供了详细的解题思路和代码实现。
摘要由CSDN通过智能技术生成

int n = board.length;

char[][] grid = new char[n][n];

for (int i = 0; i < n; i++) {

grid[i] = board[i].toCharArray();

}

int empty = 0;

for (int i = 0; i < n; i++) {

for (int j = 0; j < n; j++) {

if (grid[i][j] == ’ ') empty++;

}

}

if (empty > 0) {

if (check(grid, ‘X’)) return “X”;

if (check(grid, ‘O’)) return “O”;

return “Pending”;

}

if (check(grid, ‘X’)) return “X”;

if (check(grid, ‘O’)) return “O”;

return “Draw”;

}

private boolean check(char[][] grid, char c) {

int n = grid.length;

// 检查行

for (int row = 0; row < n; row++) {

int col;

for (col = 0; col < n; col++) {

if (grid[row][col] != c) break;

}

if (col >= n) return true;

}

// 检查列

for (int col = 0; col < n; col++) {

int row;

for (row = 0; row < n; row++) {

if (grid[row][col] != c) break;

}

if (row >= n) return true;

}

// 主对角线

int i;

for (i = 0; i < n; i++) {

if (grid[i][i] != c) break;

}

if (i >= n) return true;

// 副对角线

i = 0;

for (; i < n; i++) {

if (grid[i][n - 1 - i] != c) break;

}

return i >= n;

}

}

Q16.5 阶乘尾数

设计一个算法,算出 n 阶乘有多少个尾随零。

示例 1:

输入: 3

输出: 0

解释: 3! = 6, 尾数中没有零。

示例 2:

输入: 5

输出: 1

解释: 5! = 120, 尾数中有 1 个零.

说明: 你算法的时间复杂度应为 O(log n) 。

来源:力扣(LeetCode)

链接:https://leetcode-cn.com/problems/factorial-zeros-lcci

著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

class Solution {

public int trailingZeroes(int n) {

/*

0 是由 *10 得到的,而 10 是由 2 * 5 得到的

因此我们求 n! 过程中存在多少个 2 * 5

因为 2 的个数必定比 5 的个数多,因此我们只求 5 的个数

如果直接一个一个遍历,即

for(int i = 5; i <= n; i++){

int temp = i;

while(temp % 5 == 0){

count++;

temp /= 5;

}

}

那么 n 过大时,从 1 遍历到 n, 那么会超时,因此我们修改下规律

n! = 1 * 2 * 3 * 4 * (1 * 5) * … * (2 * 5) * … * (3 * 5) …

我们发现,

每隔 5 个数就会出现 一个 5,因此我们只需要通过 n / 5 来计算存在存在多少个 5 个数,那么就对应的存在多少个 5

但是,我们也会发现

每隔 25 个数会出现 一个 25, 而 25 存在 两个 5,我们上面只计算了 25 的一个 5,因此我们需要 n / 25 来计算存在多少个 25,加上它遗漏的 5

同时,
我们还会发现

每隔 125 个数会出现一个 125,而 125 存在 三个 5,我们上面只计算了 125 的两个 5,因此我们需要 n / 125 来计算存在多少个 125,加上它遗漏的 5

因此我们 count = n / 5 + n / 25 + n / 125 + …

最终分母可能过大溢出,上面的式子可以进行转换

count = n / 5 + n / 5 / 5 + n / 5 / 5 / 5 + …

因此,我们这样进行循环

n /= 5;

count += n;

这样,第一次加上的就是 每隔 5 个数的 5 的个数,第二次加上的就是 每隔 25 个数的 5 的个数 …

*/

int count = 0;

while(n >= 5){

n /= 5;

count += n;

}

return count;

}

}

Q16.6 最小差

给定两个整数数组a和b,计算具有最小差绝对值的一对数值(每个数组中取一个值),并返回该对数值的差

示例:

输入:{1, 3, 15, 11, 2}, {23, 127, 235, 19, 8}

输出: 3,即数值对(11, 8)

提示:

1 <= a.length, b.length <= 100000

-2147483648 <= a[i], b[i] <= 2147483647

正确结果在区间[-2147483648, 2147483647]内

来源:力扣(LeetCode)

链接:https://leetcode-cn.com/problems/smallest-difference-lcci

著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

class Solution {

public int smallestDifference(int[] a, int[] b) {

/*

对两个数组进行排序

双指针

int diff = a[i] - b[j]

如果 diff < 0 ,表示 a[i] 小于 b[j] ,a 尽可能接近 b,那么 i++

如果 diff > 0 ,表示 a[i] 大于 b[j] ,b 尽可能接近 a,那么 j++

特殊情况:

a = {1,2,3,4,5}

b = {6,7,8,9,10}

如果 a 数组最大值比 b 数组最小值还小,那么 a 数组 i 会一直右移,直到到达边界 break

*/

int alen = a.length;

int blen = b.length;

Arrays.sort(a);

Arrays.sort(b);

int minVal = Integer.MAX_VALUE;

int i = 0;

int j = 0;

while(i < alen && j < blen){

//使用 long,防止 -2147483648 转正数后还是 -2147483648

long diff = a[i] - b[j];

minVal = (int)Math.min(Math.abs(diff), minVal);

if(diff < 0){

i++;

}else{

j++;

}

}

return minVal;

}

}

Q16.7 最大数值

编写一个方法,找出两个数字ab中最大的那一个。不得使用if-else或其他比较运算符。

示例:

输入: a = 1, b = 2

输出: 2

class Solution {

public int maximum(int a, int b) {

long dif = (long)a - (long)b;

int k = (int)(dif >>> 63);

return a*(k^1) + b*k;

}

}

Q16.8 整数的英语表示

给定一个整数,打印该整数的英文描述。

示例 1:

输入: 123

输出: “One Hundred Twenty Three”

示例 2:

输入: 12345

输出: “Twelve Thousand Three Hundred Forty Five”

示例 3:

输入: 1234567

输出: “One Million Two Hundred Thirty Four Thousand Five Hundred Sixty Seven”

示例 4:

输入: 1234567891

输出: “One Billion Two Hundred Thirty Four Million Five Hundred Sixty Seven Thousand Eight Hundred Ninety One”

来源:力扣(LeetCode)

链接:https://leetcode-cn.com/problems/english-int-lcci

著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

/*

*@v7fgg

*执行用时 :17 ms, 在所有 Java 提交中击败了27.86%的用户

*内存消耗 :39.8 MB, 在所有 Java 提交中击败了100.00%的户

*2020年6月18日 22:24

*/

class Solution {

public String numberToWords(int num) {

//考虑特殊情况的0

if(num==0){return “Zero”;}

String ans="";

//原数字在后面还要用到,因此复制一份,这里只需要考虑绝对值

int m=Math.abs(num);

int yi=m%1000;//1000以内的值,也就是后三位

int qian=m/1000%1000;//多少千thousand

int baiwan=m/1000000%1000;//多少百万million

int shiyi=m/1000000000;//多少十亿billion

if(yi>0){

ans=in1000(yi);

}

if(qian>0){

ans=in1000(qian)+" Thousand "+ans;

}

if(baiwan>0){

ans=in1000(baiwan)+" Million "+ans;

}

if(shiyi>0){

ans=in1000(shiyi)+" Billion "+ans;

}

//考虑负数的情况

if(num<0){ans="Negative "+ans;}

return ans.trim();

}

public String in1000(int a){

//此函数是把一个1000以内的数字变成字符串

String shuzi1[]=new String[]{"",“One”,“Two”,“Three”,“Four”,“Five”,“Six”,“Seven”,“Eight”,“Nine”,“Ten”,“Eleven”,“Twelve”,“Thirteen”,“Fourteen”,“Fifteen”,“Sixteen”,“Seventeen”,“Eighteen”,“Nineteen”};

String shuzi2[]=new String[]{"",“Ten”,“Twenty”,“Thirty”,“Forty”,“Fifty”,“Sixty”,“Seventy”,“Eighty”,“Ninety”};

String r="";

if(a%100<20){

r=shuzi1[a%100];

a/=100;

}

else{

r=shuzi1[a%10];

a/=10;

if(a>0){

//要去掉空格,因为会出现比如:3000000 thirty thousand

r=(shuzi2[a%10]+" "+r).trim();

a/=10;

}

}

if(a>0){

//去空格是因为会出现比如:100000 one hundred thousand

r=(shuzi1[a]+" Hundred "+r).trim();

}

return r;

}

}

Q16.9 运算

请实现整数数字的乘法、减法和除法运算,运算结果均为整数数字,程序中只允许使用加法运算符和逻辑运算符,允许程序中出现正负常数,不允许使用位运算。

你的实现应该支持如下操作:

Operations() 构造函数

minus(a, b) 减法,返回a - b

multiply(a, b) 乘法,返回a * b

divide(a, b) 除法,返回a / b

示例:

Operations operations = new Operations();

operations.minus(1, 2); //返回-1

operations.multiply(3, 4); //返回12

operations.divide(5, -2); //返回-2

提示:

你可以假设函数输入一定是有效的,例如不会出现除法分母为0的情况

单个用例的函数调用次数不会超过1000次

来源:力扣(LeetCode)

链接:https://leetcode-cn.com/problems/operations-lcci

著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

import java.math.BigInteger;

class Operations {

public Operations() {

}

public int minus(int a, int b) {

return BigInteger.valueOf(a).subtract(BigInteger.valueOf(b)).intValue();

}

public int multiply(int a, int b) {

return BigInteger.valueOf(a).multiply(BigInteger.valueOf(b)).intValue();

}

public int divide(int a, int b) {

return BigInteger.valueOf(a).divide(BigInteger.valueOf(b)).intValue();

}

}

Q16.10 生存人数

给定 N 个人的出生年份和死亡年份,第 i 个人的出生年份为 birth[i],死亡年份为 death[i],实现一个方法以计算生存人数最多的年份。

你可以假设所有人都出生于 1900 年至 2000 年(含 1900 和 2000 )之间。如果一个人在某一年的任意时期处于生存状态,那么他应该被纳入那一年的统计中。例如,生于 1908 年、死于 1909 年的人应当被列入 1908 年和 1909 年的计数。

如果有多个年份生存人数相同且均为最大值,输出其中最小的年份。

示例:

输入:

birth = {1900, 1901, 1950}

death = {1948, 1951, 2000}

输出: 1901

提示:

0 < birth.length == death.length <= 10000

birth[i] <= death[i]

来源:力扣(LeetCode)

链接:https://leetcode-cn.com/problems/living-people-lcci

著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

class Solution {

public int maxAliveYear(int[] birth, int[] death) {

Q16.10 生存人数

给定 N 个人的出生年份和死亡年份,第 i 个人的出生年份为 birth[i],死亡年份为 death[i],实现一个方法以计算生存人数最多的年份。

你可以假设所有人都出生于 1900 年至 2000 年(含 1900 和 2000 )之间。如果一个人在某一年的任意时期处于生存状态,那么他应该被纳入那一年的统计中。例如,生于 1908 年、死于 1909 年的人应当被列入 1908 年和 1909 年的计数。

如果有多个年份生存人数相同且均为最大值,输出其中最小的年份。

示例:

输入:

birth = {1900, 1901, 1950}

death = {1948, 1951, 2000}

输出: 1901

提示:

0 < birth.length == death.length <= 10000

birth[i] <= death[i]

来源:力扣(LeetCode)

链接:https://leetcode-cn.com/problems/living-people-lcci

著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

class Solution {

public int maxAliveYear(int[] birth, int[] death) {

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值