ARTS第三周
Algorithm
缺失的第一个正数
给你一个未排序的整数数组,请你找出其中没有出现的最小的正整数。
示例 1:
输入: [1,2,0]
输出: 3
示例 2:
输入: [3,4,-1,1]
输出: 2
示例 3:
输入: [7,8,9,11,12]
输出: 1
提示:
你的算法的时间复杂度应为O(n),并且只能使用常数级别的额外空间。
class Solution {
public int firstMissingPositive(int[] nums) {
int len = nums.length;
int contains = 0;
for (int i=0; i<len; i++) {
if (nums[i] == 1) {
contains++;
break;
}
}
if (contains == 0) {
return 1;
}
if (len == 1) {
return 2;
}
for (int i=0; i<len; i++) {
if (nums[i] <=0 || nums[i] > len) {
nums[i] = 1;
}
}
for (int i=0; i<len; i++) {
int a = Math.abs(nums[i]);
if (a < len) {
nums[a] = - Math.abs(nums[a]);
} else {
nums[0] = - Math.abs(nums[0]);
}
}
for (int i=1; i<len; i++) {
if (nums[i] > 0) {
return i;
}
}
if (nums[0]>0) {
return len;
}
return len+1;
}
}
Review
https://eklitzke.org/beware-of-strncpy-and-strncat
如果当函数strncpy被调用的问题src
是 "supercalifragilisticexpialidocious"
。该字符串对于缓冲区而言太长,因此将仅复制前8个字节。然而,这之后dest
是 不是空值终止。这意味着,如果dest
将其传递给期望使用C样式的以null结束的字符串的函数,则该函数可能会读取缓冲区的末尾。这不完全是缓冲区溢出,因为它涉及读取而不是写入。但这仍然是一个严重的问题,因为它可能导致其他类型的内存损坏问题。
// XXX: do not do this
char dest[8];
strncpy(dest, src, sizeof(dest));
// OK: correctly copy src
char dest[8];
strncpy(dest, src, sizeof(dest) - 1);
// XXX: after this buf may not be null-terminated
strncat(buf, another_buffer, BUF_SIZE - strlen(buf));
// OK: ensure buf is null-terminated after concatenation
strncat(buf, another_buffer, BUF_SIZE - strlen(buf) - 1);
Tip
-
“面向对象编程”是一种设计思想,要点是“抽象”和“封装”,“继承”“多态”是衍生出的特性,不完全符合现实世界。
-
在 C++ 里应当少用继承和虚函数,降低对象的成本,绕过那些难懂易错的陷阱。
-
使用特殊标识符“final”可以禁止类被继承,简化类的层次关系。
-
类有六大基本函数,对于重要的构造 / 析构函数,可以使用“= default”来显式要求编译器使用默认实现。
-
“委托构造”和“成员变量初始化”特性可以让创建对象的工作更加轻松。
-
使用 using 或 typedef 可以为类型起别名,既能够简化代码,还能够适应将来的变化。