我在Leetcode OJ上做了“按频率排序字符”问题。 任何人都可以向我解释为什么会这样吗?
class Solution {
public:
struct Node {
int freq;
char ch;
};
static bool lambda(struct Node a, struct Node b){
return a.freq>b.freq;
}
string frequencySort(string s) {
if(s.size() == 0)
return "";
string res = "";
vector<Node> nums(256);
for(char c : s){
nums[(int)c].ch = c;
nums[(int)c].freq++;
}
std::sort(nums.begin(), nums.end(), Solution::lambda);
char c;
for(int i=0; nums[i].freq > 0; i++){
c = nums[i].ch;
while(nums[i].freq--){
res = res + c; // If I replace this line with res += c, it gets Accepted!
}
}
return res;
}
};
答案 0 :(得分:6)
res = res + c; // If I replace this line with res += c, it gets Accepted!
string operator+(string&, string&)
运算符将参数复制到新的字符串对象中。然后,将此临时返回值复制到res
- 这可能还涉及复制到新的更大的缓冲区。除非启用了C ++ 11,否则将使用移动分配,因此可以避免后一个可能的分配+复制。
string& operator+=(const string&)
不会创建新的字符串对象。它会就地修改现有的字符串缓冲区 - 除非需要更大的缓冲区,否则无法避免重新分配。
因此,res += c
避免在动态内存中创建临时缓冲区。如果字符串足够大,则同时使用的副本数量加倍可以使程序的峰值内存使用量大约翻倍。此外,额外的临时分配可能会增加动态内存空间的碎片,这会增加动态内存管理的开销。这两个因素可能会导致超出程序的内存限制。