Leetcode面T16(1-9)树(1),10天拿到腾讯Android岗offer

}else if(f11 == f12 && f12 == f21 && f21 == f22){//四点共线

// 没有交叉排列

if (xmax1 < xmin2 || xmax2 < xmin1){

return new double[0];

}else if(xmax1 == xmin1 && xmin1 == xmax2 && xmax2 == xmin2){//垂直的线,判断y

//没有交叉

if (ymax1 < ymin2 || ymax2 < ymin1){

return new double[0];

}else{

//取两个条线的小值中最大的,得交叉点小点

x = xmax1;

y = ymin1 > ymin2 ? ymin1 : ymin2;

return new double[]{x,y};

}

}else {

//取两个条线的小值中最大的,得交叉点小点

x = xmin1 > xmin2 ? xmin1 : xmin2;

if (start1[0] == x){

y = start1[1];

}else if(end1[0] == x){

y = end1[1];

}else if (start2[0] == x){

y = start2[1];

}else {

y = end2[1];

}

return new double[]{x,y};

}

}else{

// 线段1垂直

if (start1[0] == end1[0]){

x = start1[0];

double xue2 = 1.0*(start2[1] - end2[1])/(start2[0] - end2[0]);

double b2 = end2[1] - xue2 * end2[0];

y = xue2 * x + b2;

return new double[]{x,y};

}else if (start2[0] == end2[0]){//线段2垂直

x = start2[0];

double xue1 = 1.0*(start1[1] - end1[1])/(start1[0] - end1[0]);

double b1 = end1[1] - xue1 * end2[0];

y = xue1 * x + b1;

return new double[]{x,y};

}else {//通用情况,线段1和线段2都不垂直,计算斜率、常量值,y=a*x+b

double xue1 = 1.0*(start1[1] - end1[1])/(start1[0] - end1[0]);//斜率1

double xue2 = 1.0*(start2[1] - end2[1])/(start2[0] - end2[0]);//斜率2

double b1 = end1[1] - xue1 * end1[0];//常量b1

double b2 = end2[1] - xue2 * end2[0];//常量b2

x = (b2 - b1)/(xue1 - xue2);

y = xue1 * x + b1;

return new double[]{x,y};

}

}

}

//验证两点是否在另一条直线的同一侧,同一侧同号,不同侧异号

private int fangcheng(int x,int y,int x0,int y0,int x1,int y1){

return (x-x0)(y1-y0) - (x1-x0)(y-y0);

}

}

Q16.4 井字游戏

设计一个算法,判断玩家是否赢了井字游戏。输入是一个 N x N 的数组棋盘,由字符" ",“X"和"O"组成,其中字符” "代表一个空位。

以下是井字游戏的规则:

玩家轮流将字符放入空位(" ")中。

第一个玩家总是放字符"O",且第二个玩家总是放字符"X"。

"X"和"O"只允许放置在空位中,不允许对已放有字符的位置进行填充。

当有N个相同(且非空)的字符填充任何行、列或对角线时,游戏结束,对应该字符的玩家获胜。

当所有位置非空时,也算为游戏结束。

如果游戏结束,玩家不允许再放置字符。

如果游戏存在获胜者,就返回该游戏的获胜者使用的字符(“X"或"O”);如果游戏以平局结束,则返回 “Draw”;如果仍会有行动(游戏未结束),则返回 “Pending”。

示例 1:

输入: board = [“O X”," XO",“X O”]

输出: “X”

示例 2:

输入: board = [“OOX”,“XXO”,“OXO”]

输出: “Draw”

解释: 没有玩家获胜且不存在空位

示例 3:

输入: board = [“OOX”,“XXO”,"OX "]

输出: “Pending”

解释: 没有玩家获胜且仍存在空位

提示:

1 <= board.length == board[i].length <= 100

输入一定遵循井字棋规则

来源:力扣(LeetCode)

链接:https://leetcode-cn.com/problems/tic-tac-toe-lcci

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

class Solution {

// 井字游戏

public String tictactoe(String[] board) {

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;

}

}

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

img
img

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V:vip204888 备注Android获取(资料价值较高,非无偿)
img

总结

可以看出,笔者的工作学习模式便是由以下 「六个要点」 组成:

❝ 多层次的工作/学习计划 + 番茄工作法 + 定额工作法 + 批处理 + 多任务并行 + 图层工作法❞

希望大家能将这些要点融入自己的工作学习当中,我相信一定会工作与学习地更富有成效。

下面是我学习用到的一些书籍学习导图,以及系统的学习资料。每一个知识点,都有对应的导图,学习的资料,视频,面试题目。

**如:我需要学习 **Flutter的知识。(大家可以参考我的学习方法)

  • Flutter 的思维导图(无论学习什么,有学习路线都会事半功倍)

  • Flutter进阶学习全套手册

  • Flutter进阶学习全套视频

大概就上面这几个步骤,这样学习不仅高效,而且能系统的学习新的知识。

义、实战项目、讲解视频,并且后续会持续更新**
如果你觉得这些内容对你有帮助,可以添加V:vip204888 备注Android获取(资料价值较高,非无偿)
[外链图片转存中…(img-JNVjYAdy-1711572362225)]

总结

可以看出,笔者的工作学习模式便是由以下 「六个要点」 组成:

❝ 多层次的工作/学习计划 + 番茄工作法 + 定额工作法 + 批处理 + 多任务并行 + 图层工作法❞

希望大家能将这些要点融入自己的工作学习当中,我相信一定会工作与学习地更富有成效。

下面是我学习用到的一些书籍学习导图,以及系统的学习资料。每一个知识点,都有对应的导图,学习的资料,视频,面试题目。

**如:我需要学习 **Flutter的知识。(大家可以参考我的学习方法)

  • Flutter 的思维导图(无论学习什么,有学习路线都会事半功倍)

[外链图片转存中…(img-hdbSHhvE-1711572362225)]

  • Flutter进阶学习全套手册

[外链图片转存中…(img-XBug0F2r-1711572362226)]

  • Flutter进阶学习全套视频

[外链图片转存中…(img-VvN9J5jR-1711572362226)]

大概就上面这几个步骤,这样学习不仅高效,而且能系统的学习新的知识。

本文已被CODING开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》收录

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值