1月18号字节跳动发布全员邮件,更新了绩效和激励政策。字节跳动这次把一些12+6薪资结构的员工调整成了12+3,调整之后,员工总的年收入没有变化,这相当于月薪上升了20%。
对于这次薪资结构的调整,不少字节的员工说:表面上看是没变,实际上到手的变少了,因为月薪变高也就相当于每月交的税变多了。我觉得如果年收入不变的话,税应该不会变多,因为每年的5,6月份国家都会根据上一年的收入和交税情况来确定你应该是需要补税还是退税。


--------------下面是今天的算法题--------------
看完了字节跳动的薪资调整,我们来看道字节的面试题,这题是LeetCode的第15题:三数之和。这题字节考过很多次,除了字节以外,腾讯,京东,百度等大厂也都考过,我们来看下。


问题描述
难度:中等
给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请你返回所有和为 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组。
输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]
解释:
nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0 。
nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0 。
nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0 。
不同的三元组是 [-1,0,1] 和 [-1,-1,2] 。
注意,输出的顺序和三元组的顺序并不重要。
输入:nums = [0,1,1]
输出:[]
解释:唯一可能的三元组和不为 0 。
- 3 <= nums.length <= 3000
- -10^5 <= nums[i] <= 10^5
问题分析
这题是让找出所有三个数之和为0的三元组,这个三元组中每个元素的下标都不一样,并且还不能有重复的三元组。
这里要注意固定的第一个值num必须是小于等于0的,因为数组是有序的,如果num大于0,那么后面的数字肯定也都是大于0的,相加不可能等于0,所以这个时候可以终止查找。
因为不能有重复的三元组,所以我们每次只能固定不同的数字,如果有相同的要跳过。比如[-7,-7,3,4],第一个黑色的7和后面的3,4可以构成三元组[-7,3,4],第二个红色的-7和前面黑色的-7是一样的,如果不跳过,他也会和后面的3,4构成三元组[-7,3,4],实际上这两个三元组是一样的,也就出现了重复。
java:
public List<List<Integer>> threeSum(int[] num) { Arrays.sort(num);// 先对数组排序 List<List<Integer>> res = new ArrayList<>(); for (int i = 0; i < num.length - 2; i++) { if (i > 0 && num[i] == num[i - 1])// 过滤掉重复的 continue; // 因为是排序的,如果第一个数字大于0,那么后面的也都 // 大于0,他们三个数字的和不可能等于0 if (num[i] > 0) break; int left = i + 1;// 左指针 int right = num.length - 1;// 右指针 int target = -num[i]; while (left < right) { int sum = num[left] + num[right]; // 左右指针的和 if (sum == target) { // 找到了一组,把他们加入到集合中 res.add(Arrays.asList(num[i], num[left], num[right])); // 过滤掉重复的 while (left < right && num[left] == num[left + 1]) left++; while (left < right && num[right] == num[right - 1]) right--; left++; right--; } else if (sum < target) { left++;// 移动左指针 } else { right--;// 移动右指针 } } } return res; }
讯享网
C++:
讯享网public: vector<vector<int>> threeSum(vector<int> &nums) { sort(nums.begin(), nums.end());// 先对数组排序 vector<vector<int>> res; int length = nums.size(); for (int i = 0; i < length - 2; i++) { if (i > 0 && nums[i] == nums[i - 1])// 过滤掉重复的 continue; // 因为是排序的,如果第一个数字大于0,那么后面的也都 // 大于0,他们三个数字的和不可能等于0 if (nums[i] > 0) break; int left = i + 1;// 左指针 int right = length - 1;// 右指针 int target = -nums[i]; while (left < right) { int sum = nums[left] + nums[right]; // 左右指针的和 if (sum == target) { // 找到了一组,把他们加入到集合中 res.push_back({nums[i], nums[left], nums[right]}); // 过滤掉重复的 while (left < right && nums[left] == nums[left + 1]) left++; while (left < right && nums[right] == nums[right - 1]) right--; left++; right--; } else if (sum < target) { left++;// 移动左指针 } else { right--;// 移动右指针 } } } return res; }
C:
int cmp(const void *a, const void *b) { return *(int *) a - *(int *) b; } int threeSum(int *nums, int numsSize, int *returnSize, int returnColumnSizes) { qsort(nums, numsSize, sizeof(int), cmp);// 先排序 // 返回结果 int res = (int ) malloc(numsSize * numsSize * sizeof(int *)); *returnColumnSizes = (int *) malloc(numsSize * numsSize * sizeof(int)); *returnSize = 0;// 先初始化为0,要不然他是个不确定的值。 for (int i = 0; i < numsSize - 2; i++) { if (i > 0 && nums[i] == nums[i - 1])// 过滤掉重复的 continue; // 因为是排序的,如果第一个数字大于0,那么后面的也都 // 大于0,他们三个数字的和不可能等于0 if (nums[i] > 0) break; int left = i + 1;// 左指针 int right = numsSize - 1;// 右指针 int target = -nums[i]; while (left < right) { int sum = nums[left] + nums[right]; // 左右指针的和 if (sum == target) { // 找到了一组,把他们添加进来 res[*returnSize] = (int *) malloc(sizeof(int) * 3); res[*returnSize][0] = nums[i]; res[*returnSize][1] = nums[left]; res[*returnSize][2] = nums[right]; // 返回数组当前行的列数为3 (*returnColumnSizes)[*returnSize] = 3; (*returnSize)++; // 数组的行数自加1 // 过滤掉重复的 while (left < right && nums[left] == nums[left + 1]) left++; while (left < right && nums[right] == nums[right - 1]) right--; left++; right--; } else if (sum < target) { left++;// 移动左指针 } else { right--;// 移动右指针 } } } return res; }
Python:
讯享网def threeSum(self, nums: List[int]) -> List[List[int]]: nums.sort() # 先对数组排序 res = [] length = len(nums) for i in range(length - 2): if i > 0 and nums[i] == nums[i - 1]: # 过滤掉重复的 continue # 因为是排序的,如果第一个数字大于0,那么后面的也都 # 大于0,他们三个数字的和不可能等于0 if nums[i] > 0: break left, right = i + 1, length - 1 # 左右指针 target = -nums[i] while left < right: sum = nums[left] + nums[right] # 左右指针的和 if sum == target: # 找到了一组,把他们加入到集合中 res.append([nums[i], nums[left], nums[right]]) # 过滤掉重复的 while left < right and nums[left] == nums[left + 1]: left += 1 while left < right and nums[right] == nums[right - 1]: right -= 1 left += 1 right -= 1 elif sum < target: left += 1 # 移动左指针 else: right -= 1 # 移动右指针 return res

笔者简介
博哥,真名:王一博,毕业十多年,《算法秘籍》作者,专注于数据结构和算法的讲解,在全球30多个算法网站中累计做题2000多道,在公众号中写算法题解700多题,对算法题有自己独特的解题思路和解题技巧,喜欢的可以给个关注,也可以下载我整理的1000多页的PDF算法文档。
- 我的新书《算法秘籍》出版了。
- 公众号是怎么写出10万+的文章的。
- 理想汽车今年的校招薪资。。。


版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/23583.html