ARTS - 2020.11.09 ~ 2020.11.15

ARTS打卡 - 17

1. Algorithm

26. Remove Duplicates from Sorted Array

这是一道数组去重的题目,给定一个排序数组,去除数组中的重复元素,输出去重后的数组长度。要求空间复杂度为O(1)。题目本身比较简单,解题步骤如下:

  1. 通过两个值preValueindex分别记录前一个值以及去重后数组的下标
  2. 遍历数组,比较当前元素与preValue的值,如果相等则继续遍历。如果不相等,则交换当前元素与index的下一个元素。并记录新的preValue值。
  3. 遍历完整个数组

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 去除数组中重复元素
public int removeDuplicates(int[] nums) {
if (nums.length <= 0) return 0;
int preValue = nums[0];
int index = 0;
for (int i = 1; i < nums.length; i++) {
if (nums[i] != preValue) {
nums[++index] = nums[i];
preValue = nums[i];
} else{
continue;
}
}
return index+1;
}

后来看了一下大神们的解法,发现没有必要单独声明一个preValue,直接用新的下标就可以表示了,要更加简单一点。

2. Review

Don’t argue with default arguments

Kotlin默认参数的实现原理解析。

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
fun main(args: Array<String>) {
val testDefaultParameters = TestDefaultParameters("")
testDefaultParameters.func("position1", "position2")
}

class TestDefaultParameters (
val name: String,
val type: String = "default"
){
@JvmOverloads
fun func(p1: String, p2: String, p3: String = "default") {
// do something
}

}

将上述代码Decompile为Java后:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@JvmOverloads
public final void func(@NotNull String p1, @NotNull String p2, @NotNull String p3) {
Intrinsics.checkParameterIsNotNull(p1, "p1");
Intrinsics.checkParameterIsNotNull(p2, "p2");
Intrinsics.checkParameterIsNotNull(p3, "p3");
}

// $FF: synthetic method
public static void func$default(TestDefaultParameters var0, String var1, String var2, String var3, int var4, Object var5) {
if ((var4 & 4) != 0) {
var3 = "default";
}
var0.func(var1, var2, var3);
}

@JvmOverloads
public final void func(@NotNull String p1, @NotNull String p2) {
func$default(this, p1, p2, (String)null, 4, (Object)null);
}
...
// 调用func函数
TestDefaultParameters.func$default(testDefaultParameters, "position1", "position2", (String)null, 4, (Object)null);

可以看到上述func$default方法有6个参数,var0为Class对象,var1 ~var3 分别对应func函数的三个参数,然后有一个int类型的var4和一个Object类型的 var5var5这个大多数情况下都为null,默认参数实现的秘密主要是在这个var 4上, 看看这个方法的调用:

1
2
3
4
5
// kotlin
func("position1", "position2")

// Decompile
func$default(testDefaultParameters, "position1", "position2", (String)null, 4, (Object)null)

看到var4的值为4。是由于原函数是第三个参数为默认参数,即 position = 2位置的参数,所以 $var4 = 2^2=4$ 。在对比上述编译后的java代码, 可以看出来当var4 & 4 != 0的时候,var3的值就等于默认参数。可以发现,func$default函数的int类型的参数就是表示第几个参数的值是默认参数的。这个参数是通过位运算来计算的,例如index=0index=2的参数为默认参数,则 $var4 = 2^0 + 2^2 = 5$ 。

3. Tip

jenkins SSH执行命令只能调用/usr/bin里面的命令。而不去执行别的命令,所以只能在PATH内配置将别的路径下的命令通过软连接的方式关联起来。

4. Share

QQ音乐Android编译提速之路