20240721
- 1.题和解析
-
- [693. 交替位二进制数](#693. 交替位二进制数)
- [405. 数字转换为十六进制数](#405. 数字转换为十六进制数)
- [171 excel 表序列号](#171 excel 表序列号)
- 从这之后的是数组了
-
- [2011. 执行操作后的变量值](#2011. 执行操作后的变量值)
- [1929. 数组串联](#1929. 数组串联)
- [1720. 解码异或后的数组](#1720. 解码异或后的数组)
- 异或解析:
- [2574. 左右元素和的差值](#2574. 左右元素和的差值)
- [101. 对称二叉树](#101. 对称二叉树)
- [LCP 06. 拿硬币](#LCP 06. 拿硬币)
- [1365. 有多少小于当前数字的数字](#1365. 有多少小于当前数字的数字)
1.题和解析
693. 交替位二进制数
简单
给定一个正整数,检查它的二进制表示是否总是 0、1 交替出现:换句话说,就是二进制表示中相邻两位的数字永不相同。
bash
class Solution {
public boolean hasAlternatingBits(int n) {
int prev = 2;
while (n != 0) {
int cur = n % 2;
if (cur == prev) {
return false;
}
prev = cur;
n /= 2;
}
return true;
}
}
使用位运算:
bash
class Solution {
public boolean hasAlternatingBits(int n) {
int a = n ^ (n >> 1);
return (a & (a + 1)) == 0;
}
}
分析:
bash
假设 n 的二进制表示为 101010:
n >> 1 的结果是 010101。
n ^ (n >> 1) 的结果是 111111。
a = 111111,a + 1 = 1000000。
a & (a + 1) = 111111 & 1000000 = 0,符合条件。
因此,(a & (a + 1)) == 0 为 true,说明 n 的位是交替的。
1010
0101
----
1111
405. 数字转换为十六进制数
都是位运算
官解:
bash
class Solution {
public String toHex(int num) {
if (num == 0) {
return "0";
}
StringBuffer sb = new StringBuffer();
for (int i = 7; i >= 0; i --) {
int val = (num >> (4 * i)) & 0xf;
if (sb.length() > 0 || val > 0) {
char digit = val < 10 ? (char) ('0' + val) : (char) ('a' + val - 10);
sb.append(digit);
}
}
return sb.toString();
}
}
其他的:
bash
class Solution {
public String toHex(int num) {
// 负数 a 取反加上 a 的绝对值后,答案的二进制为32位1,在 long 中代表 (long)Math.pow(2, 32) - 1
// 因此 负数 a 取反后加一的二进制和 (long)Math.pow(2, 32) 一样,16进制固然也一样
if (num == 0) {
return "0";
}
long a = num >= 0 ? num : (long)Math.pow(2, 32) + num;
StringBuilder sb = new StringBuilder();
while (a != 0) {
int mod = (int)(a % 16);
if (mod > 9) {
sb.append((char)('a' + mod - 10));
} else {
sb.append(mod);
}
a = a / 16;
}
return sb.reverse().toString();
}
}
171 excel 表序列号
bash
class Solution {
public int titleToNumber(String columnTitle) {
int n = columnTitle.length(); // 获取列标题的长度
int ans = 0; // 初始化结果变量
for(int i = 0; i < n; i++) { // 遍历列标题中的每个字符
ans = ans * 26 + (columnTitle.charAt(i) - 'A' + 1); // 将当前字符转换为数字并累加到结果中,.charAt(i)拿到第i个字符,通过ASCII码也行
}
return ans; // 返回最终的列号
}
}
ASCII:
bash
// 获取索引为 1 的字符
char ch = str.charAt(1);
// 获取该字符的 ASCII 码
int asciiCode = (int) ch;
从这之后的是数组了
2011. 执行操作后的变量值
存在一种仅支持 4 种操作和 1 个变量 X 的编程语言:
++X 和 X++ 使变量 X 的值 加 1
--X 和 X-- 使变量 X 的值 减 1
最初,X 的值是 0
给你一个字符串数组 operations ,这是由操作组成的一个列表,返回执行所有操作后, X 的 最终值 。
终于和官解一样了!!
bash
class Solution {
public int finalValueAfterOperations(String[] operations) {
int sum=0;
for(String op:operations){
if(op.equals("X++")||op.equals("++X")){
sum++;
}else{
sum--;
}
}
return sum;
}
}
1929. 数组串联
给你一个长度为 n 的整数数组 nums 。请你构建一个长度为 2n 的答案数组 ans ,数组下标 从 0 开始计数 ,对于所有 0 <= i < n 的 i ,满足下述所有要求:
ans[i] == nums[i]
ans[i + n] == nums[i]
具体而言,ans 由两个 nums 数组 串联 形成。
返回数组 ans 。
官解:
bash
class Solution {
public int[] getConcatenation(int[] nums) {
int length = nums.length;
int[] ans = new int[length << 1];
for (int i = 0; i < length; i++) {
ans[i + length]= ans[i] = nums[i];
}
return ans;
}
}
1720. 解码异或后的数组
未知 整数数组 arr 由 n 个非负整数组成。
经编码后变为长度为 n - 1 的另一个整数数组 encoded ,其中 encoded[i] = arr[i] XOR arr[i + 1] 。例如,arr = [1,0,2,1] 经编码后得到 encoded = [1,2,3] 。
给你编码后的数组 encoded 和原数组 arr 的第一个元素 first(arr[0])。
请解码返回原数组 arr 。可以证明答案存在并且是唯一的。
bash
class Solution {
public int[] decode(int[] encoded, int first) {
int n = encoded.length + 1;//首先先拿到原数组的长度
int[] arr = new int[n];//定义一个原数组长度的数组
arr[0] = first;//把第一个元素放进去
for (int i = 1; i < n; i++) {
arr[i] = arr[i - 1] ^ encoded[i - 1];//这个就是带公式
}
return arr;
}
}
异或解析:
OR(异或)是一种二进制逻辑运算,其符号通常为 ^。XOR 运算的规则是:如果两个相应的二进制位相同,则结果为 0,如果不同,则结果为 1。
下面是如何进行 XOR 运算的步骤:
按位运算:XOR 是按位进行的运算,这意味着你需要将两个数字转换为二进制形式,并对每一位分别进行 XOR 运算。
运算规则:
bash
0 XOR 0 = 0
0 XOR 1 = 1
1 XOR 0 = 1
1 XOR 1 = 0
结果组合:将每一位的 XOR 运算结果组合起来,形成最终的二进制结果,然后可以将其转换回十进制。
示例
假设我们要计算 5 XOR 3:
转换为二进制:
bash
5 的二进制是 101
3 的二进制是 011
按位进行 XOR 运算:
bash
第一位(从右向左数):1 XOR 1 = 0
第二位:0 XOR 1 = 1
第三位:1 XOR 0 = 1
组合结果:
得到的二进制结果是 110
转换回十进制:
bash
110 在二进制中对应的十进制数是 6
所以,5 XOR 3 的结果是 6。
在编程中,你可以使用编程语言提供的 XOR 运算符(通常是 ^)来直接进行 XOR 运算,而不需要手动转换和执行每一位的运算。例如,在 Python 中,你可以这样计算:
result = 5 ^ 3
print(result) # 输出将是 6
2574. 左右元素和的差值
给你一个下标从 0 开始的整数数组 nums ,请你找出一个下标从 0 开始的整数数组 answer ,其中:
answer.length == nums.length
answer[i] = |leftSum[i] - rightSum[i]|
其中:
leftSum[i] 是数组 nums 中下标 i 左侧元素之和。如果不存在对应的元素,leftSum[i] = 0 。
rightSum[i] 是数组 nums 中下标 i 右侧元素之和。如果不存在对应的元素,rightSum[i] = 0 。
返回数组 answer 。
bash
class Solution {
public int[] leftRigthDifference(int[] nums) {
int n = nums.length;
int[] ans = new int[n];
ans[0] = nums[0];
for (int i = 1; i < n; ++i) {
ans[i] = ans[i - 1] + nums[i];
}
for (int i = n - 1, rs = 0; i >= 0; rs += nums[i--]) {
int ls = i == 0 ? 0 : ans[i - 1];
ans[i] = Math.abs(ls - rs);
}
return ans;
}
}
题解:(理解题目就很简单了)
bash
示例
假设 nums = [1, 2, 3, 4]:
计算 leftSum:
leftSum[0] = 0(没有左侧元素)
leftSum[1] = 1(只有 1 左侧元素)
leftSum[2] = 3(1 + 2 左侧元素)
leftSum[3] = 6(1 + 2 + 3 左侧元素)
计算 rightSum:
rightSum[0] = 9(2 + 3 + 4 右侧元素)
rightSum[1] = 7(3 + 4 右侧元素)
rightSum[2] = 4(4 右侧元素)
rightSum[3] = 0(没有右侧元素)
计算 answer:
answer[0] = |0 - 9| = 9
answer[1] = |1 - 7| = 6
answer[2] = |3 - 4| = 1
answer[3] = |6 - 0| = 6
最终,answer 数组是 [9, 6, 1, 6]。
101. 对称二叉树
给你一个二叉树的根节点 root , 检查它是否轴对称。
示例 1:
输入:root = [1,2,2,3,4,4,3]
输出:true
bash
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public boolean isSymmetric(TreeNode root) {
return check(root, root);
}
public boolean check(TreeNode p, TreeNode q) {
if (p == null && q == null) {
return true;
}
if (p == null || q == null) {
return false;
}
return p.val == q.val && check(p.left, q.right) && check(p.right, q.left);
}
}
LCP 06. 拿硬币
桌上有 n 堆力扣币,每堆的数量保存在数组 coins 中。我们每次可以选择任意一堆,拿走其中的一枚或者两枚,求拿完所有力扣币的最少次数。
示例 1:
输入:[4,2,1]
输出:4
解释:第一堆力扣币最少需要拿 2 次,第二堆最少需要拿 1 次,第三堆最少需要拿 1 次,总共 4 次即可拿完。
bash
class Solution {
public int minCount(int[] coins) {
int sum = 0;
for (int i : coins) {
sum += (i + 1) / 2;
}
return sum;
}
}
1365. 有多少小于当前数字的数字
简单
相关标签
相关企业
提示
给你一个数组 nums,对于其中每个元素 nums[i],请你统计数组中比它小的所有数字的数目。
换而言之,对于每个 nums[i] 你必须计算出有效的 j 的数量,其中 j 满足 j != i 且 nums[j] < nums[i] 。
以数组形式返回答案。
示例 1:
输入:nums = [8,1,2,2,3]
输出:[4,0,1,1,3]
解释:
对于 nums[0]=8 存在四个比它小的数字:(1,2,2 和 3)。
对于 nums[1]=1 不存在比它小的数字。
对于 nums[2]=2 存在一个比它小的数字:(1)。
对于 nums[3]=2 存在一个比它小的数字:(1)。
对于 nums[4]=3 存在三个比它小的数字:(1,2 和 2)。
bash
class Solution {
public int[] smallerNumbersThanCurrent(int[] nums) {
int n = nums.length;
int[] ret = new int[n];
for (int i = 0; i < n; i++) {
int cnt = 0;
for (int j = 0; j < n; j++) {
if (nums[j] < nums[i]) {
cnt++;
}
}
ret[i] = cnt;
}
return ret;
}
}