今天看到一个讨论,挺有意思的:有网友建议把程序员的工资统一定在10k,反正人多,干嘛非得给每个人单独定薪水。
更有意思的是,下面还有人建议程序员应该“国有化”,纳入编制,直接和公务员一样。
统一10k工资的建议,虽然听起来有点戏谑,但是建议国有化我觉得挺好的,稳定有保障还能干到退休。
好吧,说说我的看法,程序员的工资不应该被统一化定死,毕竟我们工作内容的差异化和公司需求的多样性,决定了薪资的灵活性。
还是要根据个人的技术深度和项目经验来定薪,而不是一个“10k政策”就能解决的事情。
但如果真能像公务员那样享受一些福利,倒是能省点心,少点焦虑。只是……那个工作量可能会大得惊人吧。
算法题:不含连续1的非负整数
今天给大家带来一道有点意思的算法题。
题目看似简单,但它在细节处理上其实挺考验咱们的编程功力。这道题是这样的:我们需要找出所有不含连续1的非负整数。
在解决这个问题之前,我先给大家举个例子。假设我们要求不含连续1的非负整数范围是0到10,那么这些整数应该是:0, 1, 2, 4, 5, 8, 9
。为什么这样呢?因为2、3、6、7、10这些数字都包含了两个连续的1。
OK,问题不难理解,接下来就是怎么去写代码了。其实,这类问题的核心思想通常是通过动态规划(DP)或者利用位运算来解决。
思路1:动态规划
我们可以通过动态规划的方式来解决这个问题。我们定义一个dp数组,其中dp[i]
表示i位二进制的数字中,不含连续1的数的个数。要注意的是,二进制中连续的1会使得我们不符合条件,所以我们需要对这种情况进行处理。
动态规划的状态转移方程是这样的:
如果当前位为0,那么可以在前一位上加上一个0或1,两种选择都可以。 如果当前位为1,那么前一位必须是0,也就是说,这个数字的前一位只能是0,后续的部分可以继续选择。
从上面的描述,我们不难看出,当前状态只依赖于前两位的状态。所以我们可以定义两个状态:
dp[i]
表示包含i位的数字中不包含连续1的数字个数。通过状态转移的关系,我们可以从低位逐渐推算到高位。
Java代码实现:
public class NonConsecutiveOnes {
public static int countNonConsecutiveOnes(int n) {
if (n == 0) return 1; // 特殊情况,0个二进制位只有1种情况
int[] dp = new int[n + 1];
dp[0] = 1; // 0位的情况,只有1个数字
dp[1] = 2; // 1位的情况,分别是0和1
for (int i = 2; i <= n; i++) {
dp[i] = dp[i - 1] + dp[i - 2]; // 当前位为0可以接在前面的任意情况,当前位为1则前一位必须为0
}
return dp[n];
}
public static void main(String[] args) {
int n = 5; // 假设我们想计算5位二进制的情况
System.out.println("不含连续1的非负整数个数: " + countNonConsecutiveOnes(n));
}
}
解释:
这段代码通过动态规划来解决问题。我们先初始化了dp[0]
和dp[1]
,分别代表0位和1位二进制数的有效情况数。接着,我们使用一个循环从2位到n位,逐步更新dp数组。dp[i]
的值等于dp[i-1] + dp[i-2]
,这代表了当前位可以是0或1的两种情况。最终,dp[n]
就存储了n位二进制数中不包含连续1的数字个数。
思路2:斐波那契数列
其实,看到上面的动态规划代码,你会发现,它实际上和斐波那契数列有点像!因为每个状态的值是前两个状态的和,和斐波那契数列一样。因此,我们还可以通过斐波那契数列的方式来解决这个问题。
斐波那契实现:
public class NonConsecutiveOnes {
public static int countNonConsecutiveOnes(int n) {
if (n == 0) return 1;
if (n == 1) return 2;
int a = 1, b = 2; // 初始化前两项,a代表dp[i-2],b代表dp[i-1]
for (int i = 2; i <= n; i++) {
int temp = a + b; // 当前状态的值等于前两项之和
a = b; // 更新a
b = temp; // 更新b
}
return b;
}
public static void main(String[] args) {
int n = 5;
System.out.println("不含连续1的非负整数个数: " + countNonConsecutiveOnes(n));
}
}
解释:
这个版本通过直接计算斐波那契数列来获得答案。a
和b
分别表示dp[i-2]
和dp[i-1]
,每次循环通过更新它们的值来计算当前状态。这个方法的时间复杂度是O(n),而且我们只需要常数级别的空间,所以性能更优。
总结
无论是通过动态规划还是斐波那契数列的方式,我们都能高效地解决这道“不含连续1的非负整数”问题。动态规划让我们清晰地看到问题的状态转移,而斐波那契数列则进一步简化了问题的处理,减少了空间复杂度。
这道题其实就是一个典型的思维训练题,帮助我们更好地理解状态转移、递推关系等算法技巧。至于遇到这种题目时,脑袋要快一点,心中有个清晰的思路,代码自然就写出来了。
其实在实际工作中,我们经常会遇到类似的题目,比如用来计算某些二进制数的特性,或者在进行动态规划的时候,如何将问题拆解成子问题。
-END-
以上,就是今天的分享了,看完文章记得右下角给何老师点赞,也欢迎在评论区写下你的留言。