@美国求职
美国求职
将近而立之年,机缘巧合来到了美国,重新开始了程序员的求职之路,我会用几篇文章的篇幅记录下我整个求职的心路历程和准备过程
面试准备
美国的公司面试对算法部分很重视,所以算法部分的准备也是重中之重,所以一把年纪还要重新开始啃算法书,刷LeetCode。
第一天
LeetCode 1 Two Sum
Given an array of integers, return indices of the two numbers such that they add up to a specific target.
You may assume that each input would have exactly one solution, and you may not use the same element twice.
Example:
Given nums = [2, 7, 11, 15], target = 9,
Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].
//Version1
class Solution {
public int[] twoSum(int[] nums, int target) {
int length = nums.length;
int result[] = new int[2];
for (int i = 0; i < length; i++) {
result[0] = i;
int j = target - nums[result[0]];
for (int k = 0; k < length; k++) {
if (k != result[0] && nums[k] == j) {
result[1] = k;
return result;
}
}
}
return null;
}
}
参考下答案,发现自己的算法度渣的一比,最优解的算法复杂的是O(n),于是顺带复习一下算法复杂度的知识:
时间复杂度
O(1)<O(logn)<O(n)<O(nlogn)<O(n²)<O(n³)<O(2ⁿ)<O(n!)
关于如何鉴别算法复杂度就不赘述了,其中O(2ⁿ)著名的斐波那契递归算法复杂度
我们version1的算法复杂度是O(n²),显然是非常Brute Force(暴力)的Approach,这里我们需要使用hashtable来减少一层循环,即用空间换时间——trading space for speed.
//Version2
class Solution {
public int[] twoSum(int[] nums, int target) {
Map<Integer, Integer> hash = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
int complement = target - nums[i];
if (hash.containsKey(complement)) {
return new int[]{i, hash.get(complement)};
} else {
hash.put(nums[i], i);
}
}
// replace return null
throw new IllegalArgumentException("No two sum solution");
}
}
利用hashmap后,我们的算法复杂度降到了O(n),这种思想方法同时也会大量的使用在日后的算法优化中,需熟练掌握。
同时我们对异常的返回也做了优化,之前是直接返回null,现在调优为抛出一个异常更为人性化。
LeetCode 7 Reverse Integer
我们的刷题路线是 简->中->难,所以这是简单排序中的第二题。
Given a 32-bit signed integer, reverse digits of an integer.
Example 1: Input: 123 Output: 321
Example 2:Input: -123 Output: -321
Example 3: Input: 120 Output: 21
Note: Assume we are dealing with an environment which could only store integers within the 32-bit signed integer range: [−2^31, 2^31 − 1]. For the purpose of this problem, assume that your function returns 0 when the reversed integer overflows.
这个题首先想到的解法是字符串反转
//Version String
public int reverse(int x) {
String a = Integer.toString(x);
int b = 1;
if (a.charAt(0) == '-') {
a = a.substring(1);
b = -1;
}
char[] chars = a.toCharArray();
char[] results = new char[chars.length];
for (int i = chars.length - 1; i >= 0; i--) {
results[chars.length - 1 - i] = chars[i];
}
long longNum = Long.valueOf(new String(results));
if (longNum > Integer.MAX_VALUE || longNum < Integer.MIN_VALUE) {
return 0;
}
return (int) (b * longNum);
}
主要解题思想就是把先判断符号,然后把剩下的String转为char[]做个反转,同时要注意溢出的情况,算法复杂度O(n),另一种方法是对10取余
//Version remainder
public int reverse2(int x) {
long result = 0;
while (x != 0) {
result = result * 10 + x % 10;
x = x / 10;
}
if (result > Integer.MAX_VALUE || result < Integer.MIN_VALUE) {
return 0;
}
return (int) result;
}
时间复杂度为O(logn)