首页
学习
活动
专区
圈层
工具
发布

外包竟敢用vim,我一个正编都没敢用 。。

今天看到一个有意思的帖子,标题是“外包竟敢用vim,我一个正编都没敢用”。看得我不禁笑出声来,心想这位网友怕是对vim有点误解。

作为一名老程序员,我可以理解为什么新手看到vim会觉得头大。毕竟它那种模式化的编辑方式,起初确实让人迷惑不解。你一不小心按错一个键,屏幕上就满是各种让你心碎的乱码——这让我不禁想起我刚接触vim时的情景,那简直是血泪史。

但说实话,vim它的强大之处在于,经过一段时间的学习后,你会发现它的高效和灵活性简直让人上瘾。它没有鼠标这一“拖慢工作速度”的东西,整个编程过程变得非常流畅。我记得一开始也是不敢轻易用vim,怕出错怕崩溃。但随着时间的推移,你会渐渐习惯它的“心跳”,甚至离不开它。

老实说,外包用vim并不代表什么,反倒是能看出他们已经在追求更高效的工作方式了。如果你还在用传统的编辑器,不妨试试vim,换个角度看看编程的世界,或许会有意外的收获哦。

算法题:最大单词长度乘积

聊一个我觉得有点意思的算法题:最大单词长度乘积。你可能会想,这个题目听起来有点抽象,但其实如果理清楚思路,解决起来是相当直观的。

问题背景

题目大概的意思是,给你一个字符串数组,你需要找到两个单词,这两个单词必须是互不相交的(即它们的字符集没有任何重合),然后返回这两个单词长度的乘积。简单点说,就是你要找两个长度较大的单词,它们的字符完全不同。然后计算它们长度的乘积。

举个简单例子:

words = ["abcw", "baz", "foo", "bar", "xtfn", "abcdef"]

这里面,“abcw”和“xtfn”是互不相交的两个单词,因为它们的字母集合没有重合,最大长度分别是4和4。所以它们的长度乘积就是16。

解决思路

如何高效地解决这个问题呢?我们可以通过位运算来简化判断单词字符集是否有重合。具体思路是:

通过位掩码(Bitmask)表示单词的字符集:我们可以用一个32位的整数来表示一个单词的字符集。假设字母是小写字母,那么每个字母就对应一个位置。例如,字母'a'对应的就是二进制的第0位,字母'b'对应第1位,依此类推。这样,对于一个单词,我们可以计算出它的掩码。

遍历所有单词:将每个单词转化为位掩码,并保存在一个数组中。

通过位运算判断是否有重合:对于每一对单词,我们用位运算“与(&)”来判断它们是否有共同的字符。如果结果为0,说明这两个单词没有字符重合,就可以计算它们的长度乘积。

代码实现

public class Solution {

public int maxProduct(String[] words) {

int n = words.length;

int[] bitMasks = new int[n];

// 将每个单词转换成位掩码

for (int i = 0; i < n; i++) {

int mask = 0;

for (char c : words[i].toCharArray()) {

mask |= 1 << (c - 'a');  // 设置字符对应位置为1

}

bitMasks[i] = mask;

}

int maxProduct = 0;

// 遍历所有单词对,判断是否有重合字符

for (int i = 0; i < n; i++) {

for (int j = i + 1; j < n; j++) {

if ((bitMasks[i] & bitMasks[j]) == 0) {  // 没有重合字符

maxProduct = Math.max(maxProduct, words[i].length() * words[j].length());

}

}

}

return maxProduct;

}

}

解释

位掩码的计算:对于每个单词,我们通过循环遍历每个字符,然后通过 1 << (c - 'a') 将对应的字母位置上的位设置为1。例如,字母'a'对应二进制的第0位,字母'b'对应第1位,依此类推。这样,我们就能将一个单词转化为一个整数,表示它的字符集。

位运算判断:当我们对两个单词的掩码做与(&)运算时,如果结果为0,说明它们没有重合的字符。这是因为没有重合的字符会导致位运算结果为0,表示两者的字符集合是独立的。

最大乘积的计算:每次当发现两个单词字符集没有重合时,我们就计算它们长度的乘积,并更新最大乘积。

时间复杂度

这个解法的时间复杂度主要来自两个部分:

转换单词为位掩码:我们需要遍历每个单词,并且每个单词最多有26个字母,所以这一部分的复杂度是 O(n * m),其中 n 是单词数量,m 是单词的最大长度。

检查所有单词对:我们需要检查每一对单词是否有字符重合。最坏情况下,检查所有单词对的复杂度是 O(n^2)。

因此,整体时间复杂度是 O(n^2),其中 n 是单词的数量。对于较小的输入,这个复杂度是完全可以接受的。

这个题目通过位运算的技巧,将一个看似复杂的字符比较问题转化成了整数的位运算问题,极大地提高了效率。通过这种方法,我们避免了直接比较两个单词中的每个字符,从而减少了不必要的计算。

当然了,如果你不习惯用位运算,也可以考虑其他的优化方式,但我觉得位运算这种思路对于这种问题来说是相当简洁高效的。至于结果,像这种题目就是那种“你做对了就能一口气做完,做错了也没办法后悔”的类型,所以我觉得能用位运算解决就挺爽的。

  • 发表于:
  • 原文链接https://page.om.qq.com/page/OCEfm7PCaW6fZnq-NCJ36DFA0
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

相关快讯

领券