职位网站 Levels.fyi 日前发布了一份《2023 年年终薪资报告》,该报告收集了全球数千家公司的超过 200,000 份程序员的薪资数据,主要反映程序员在2023年薪酬总额的中位数,包括工资,股票和奖金。
从美国方面来看,程序员收入最高的地区是旧金山,薪资中位数是 24.9 万美元,约合人民币178.44万元人民币,目前汇率(一直变动):1 美元 ≈ 7.166 人民币。中位数能达到 24.9 万美元,就目前来看旧金山是全球程序员收入最高的城市了。
在看一下欧洲方面的数据,除了瑞士的苏黎世工资比较高以外,其他城市的程序员工资相对来说并不是很高,这个确实挺意外,我印象中欧洲的人均收入都比较高,但欧洲程序员的收入相比人均收入并没有高的很离谱。
最后再来看下其他地区的薪资,程序员收入最高的地区是以色列的特拉维夫,中位数薪资约为 13.8 万美元(约 98.9 万元人民币);排在第六的是中国北京,年中位数收入为 9万美元(约 64.5 万元人民币)。
北京程序员中位数年收入在60多万,这个应该统计的都是大厂的数据,在北京很多小的互联网公司,程序员的最高收入也不一定能达到60多万。
看完了程序员的薪资,我们来看一道算法题吧,这题是LeetCode的第35题:搜索插入位置,这题实际上是一道二分查找题,比较简单,我们来看下。
问题描述
来源:LeetCode第35题
难度:简单
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
请必须使用时间复杂度为 O(log n) 的算法。
示例1:
输入: nums = [1,3,5,6], target = 5
输出: 2
示例2:
输入: nums = [1,3,5,6], target = 2
输出: 1
1 <= nums.length <= 10^4
-10^4 <= nums[i] <= 10^4
nums 为无重复元素的升序排列数组
-10^4 <= target <= 10^4
问题分析
这题让查找目标值在数组中的位置,如果没找到就返回目标值应该插入的位置,这是一道典型的二分查找题。对于二分查找可以使用左闭右闭和左闭右开两种方式,无论哪种方式都要注意防止出现死循环。
防止出现死循环的判断也比较简单,就是无论是开区间还是闭区间,每次 while 循环的时候,两个指针必须要有一个指针的值发生改变。我们这里就以左闭右开区间来分析下,解题步骤如下:
1,使用两个指针一个指向查询区域的左端 left ,一个指向查询区域右端的下一个位置 right ,每次取区域内 [left,right) 中间位置的值。
2,如果目标值等于中间值,说明找到了,直接返回 mid 。
3,如果目标值大于中间值,说明中间值及前面部分太小了,下一步需要往后半部分查找 [mid+1,right) 。
4,如果目标值小于中间值,说明中间值及后面部分太大了,但中间值有可能是需要插入的位置,所以中间值的位置不能排除,下一步需要往前半部分查找 [left,mid) 。
因为 right 是开区间,当 left >= right 的时候说明查询区间为空,终止循环,所以循环执行的条件是 left < right 。
JAVA:
public int searchInsert(int[] nums, int target) {
int left = 0;// 左边界,闭区间。
int right = nums.length;// 右边界,开区间。
while (left < right) {
int mid = (left + right) >>> 1;// 中间值。
if (nums[mid] == target)
return mid;
else if (nums[mid] < target) {
left = mid + 1; // 缩小范围到[mid+1,right]
} else {// if (nums[mid] > target)
right = mid; // 缩小范围到[left,mid)
}
}
return right;// 或者return left;
}
C++:
public:
int searchInsert(vector<int>& nums, int target) {
int left = 0;// 左边界,闭区间。
int right = nums.size();// 右边界,开区间。
while (left < right) {
int mid = left + (right-left)/2 ;// 中间值。
if (nums[mid] == target)
return mid;
else if (nums[mid] < target) {
left = mid + 1; // 缩小范围到[mid+1,right]
} else {// if (nums[mid] > target)
right = mid; // 缩小范围到[left,mid)
}
}
return right;// 或者return left;
}
C:
int searchInsert(int* nums, int numsSize, int target) {
int left = 0;// 左边界,闭区间。
int right = numsSize;// 右边界,开区间。
while (left < right) {
int mid = left + (right-left)/2 ;// 中间值。
if (nums[mid] == target)
return mid;
else if (nums[mid] < target) {
left = mid + 1; // 缩小范围到[mid+1,right]
} else {// if (nums[mid] > target)
right = mid; // 缩小范围到[left,mid)
}
}
return right;// 或者return left;
}
Python:
def searchInsert(self, nums: List[int], target: int) -> int:
left, right = 0, len(nums)
while left < right:
mid = (left + right) // 2
if nums[mid] == target:
return mid
elif nums[mid] < target:
left = mid + 1 # 缩小范围到[mid+1, right]
else: # if (nums[mid] > target)
right = mid # 缩小范围到[left, mid)
return right
-------------------------end-------------------------
笔者简介
博哥,真名:王一博,毕业十多年,《算法秘籍》作者,专注于数据结构和算法的讲解,在全球30多个算法网站中累计做题2000多道,在公众号中写算法题解700多题,对算法题有自己独特的解题思路和解题技巧,喜欢的可以给个关注,也可以下载我整理的1000多页的PDF算法文档。