LeetCode 507. 完美数 / 2022. 将一维数组转变成二维数组 / 390. 消除游戏(等差数列模拟,约瑟夫环)
Posted Zephyr丶J
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode 507. 完美数 / 2022. 将一维数组转变成二维数组 / 390. 消除游戏(等差数列模拟,约瑟夫环)相关的知识,希望对你有一定的参考价值。
507. 完美数
2021.12.31 每日一题,年底最后一题,祝大家新年快乐
题目描述
对于一个 正整数,如果它和除了它自身以外的所有 正因子 之和相等,我们称它为 「完美数」。
给定一个 整数 n, 如果是完美数,返回 true,否则返回 false
示例 1:
输入:num = 28
输出:true
解释:28 = 1 + 2 + 4 + 7 + 14
1, 2, 4, 7, 和 14 是 28 的所有正因子。
示例 2:
输入:num = 6
输出:true
示例 3:
输入:num = 496
输出:true
示例 4:
输入:num = 8128
输出:true
示例 5:
输入:num = 2
输出:false
提示:
1 <= num <= 10^8
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/perfect-number
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
class Solution
public boolean checkPerfectNumber(int num)
//相当于找因子
if(num < 2)
return false;
int range = (int)Math.sqrt(num);
int res = 1;
for(int i = 2; i <= range; i++)
if(num % i == 0)
res += i + num / i;
return num == res;
2022. 将一维数组转变成二维数组
2022.1.1 每日一题 新年快乐啊!!!!!
题目描述
给你一个下标从 0 开始的一维整数数组 original 和两个整数 m 和 n 。你需要使用 original 中 所有 元素创建一个 m 行 n 列的二维数组。
original 中下标从 0 到 n - 1 (都 包含 )的元素构成二维数组的第一行,下标从 n 到 2 * n - 1 (都 包含 )的元素构成二维数组的第二行,依此类推。
请你根据上述过程返回一个 m x n 的二维数组。如果无法构成这样的二维数组,请你返回一个空的二维数组。
示例 1:
输入:original = [1,2,3,4], m = 2, n = 2
输出:[[1,2],[3,4]]
解释:
构造出的二维数组应该包含 2 行 2 列。
original 中第一个 n=2 的部分为 [1,2] ,构成二维数组的第一行。
original 中第二个 n=2 的部分为 [3,4] ,构成二维数组的第二行。
示例 2:
输入:original = [1,2,3], m = 1, n = 3
输出:[[1,2,3]]
解释:
构造出的二维数组应该包含 1 行 3 列。
将 original 中所有三个元素放入第一行中,构成要求的二维数组。
示例 3:
输入:original = [1,2], m = 1, n = 1
输出:[]
解释:
original 中有 2 个元素。
无法将 2 个元素放入到一个 1x1 的二维数组中,所以返回一个空的二维数组。
示例 4:
输入:original = [3], m = 1, n = 2
输出:[]
解释:
original 中只有 1 个元素。
无法将 1 个元素放满一个 1x2 的二维数组,所以返回一个空的二维数组。
提示:
1 <= original.length <= 5 * 10^4
1 <= original[i] <= 10^5
1 <= m, n <= 4 * 10^4
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/convert-1d-array-into-2d-array
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
class Solution
public int[][] construct2DArray(int[] original, int m, int n)
//2022年第一道题是2022题
int l = original.length;
if(l != m * n)
return new int[][];
int[][] ans = new int[m][n];
int idx = 0;
for(int i = 0; i < m; i++)
for(int j = 0; j < n; j++)
ans[i][j] = original[idx++];
return ans;
390. 消除游戏
2022.1.2 每日一题
题目描述
列表 arr 由在范围 [1, n] 中的所有整数组成,并按严格递增排序。请你对 arr 应用下述算法:
从左到右,删除第一个数字,然后每隔一个数字删除一个,直到到达列表末尾。
重复上面的步骤,但这次是从右到左。也就是,删除最右侧的数字,然后剩下的数字每隔一个删除一个。
不断重复这两步,从左到右和从右到左交替进行,直到只剩下一个数字。
给你整数 n ,返回 arr 最后剩下的数字。
示例 1:
输入:n = 9
输出:6
解释:
arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]
arr = [2, 4, 6, 8]
arr = [2, 6]
arr = [6]
示例 2:
输入:n = 1
输出:1
提示:
1 <= n <= 10^9
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/elimination-game
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
这个等差数列的好理解
class Solution
public int lastRemaining(int n)
//先删除1 3 5 7 9
//找了下规律,先删除2倍的,再四倍的,再8倍
//刚开始是奇数删掉,然后看从哪个数字开始,每隔4删除一次,然后是每隔8
//所以记录左右的起始位置就可以了
//然后发现不会记,总感觉会漏掉值
//然后看了题解,发现只需要统计左边第一个数就行了
int left = 1;
int base = 1;
int k = 0;
int count = n;
while(count > 1)
//从左到右删除,那么删除以后,最左边的数就是第二个数
if(k % 2 == 0)
left = left + base;
else
//如果当前数目是偶数,那么左边不会删除;如果是奇数,那么左边会删除,而下一个位置也是加base
if(count % 2 == 1)
left = left + base;
base <<= 1;
count >>= 1;
k++;
return left;
约瑟夫环公式推导问题
从左到右删除,剩下的数定义为a,f[i]
从右到左删除,剩下的数定义为b, g[i]
总数为i,那么a + b = n + 1,f[i] + g[i] = i + 1
然后和约瑟夫环一样,刚开始删除奇数,也就是1 3 5 7…得到了f[i]
此时,剩下g[i/2],同时f[i] = 2 * g[i / 2]
代入上面的第一个公式,得到f[i] = 2 * (i / 2 + 1 - f[i / 2] )
然后就可以使用递归的思想,得到最后的结果
挺难的,不好想
class Solution
public int lastRemaining(int n)
return n == 1 ? 1 : 2 * (n / 2 + 1 - lastRemaining(n / 2));
以上是关于LeetCode 507. 完美数 / 2022. 将一维数组转变成二维数组 / 390. 消除游戏(等差数列模拟,约瑟夫环)的主要内容,如果未能解决你的问题,请参考以下文章
LeetCode 507 完美数[枚举] HERODING的LeetCode之路