14.最长公共前缀
编写一个函数来查找字符串数组中的最长公共前缀。
如果不存在公共前缀,返回空字符串 ""
。
示例 1:
输入:strs = ["flower","flow","flight"] 输出:"fl"
示例 2:
输入:strs = ["dog","racecar","car"] 输出:"" 解释:输入不存在公共前缀。
思路详解:本题我们采用横向对齐的办法来解决,先记录第一个字符串称为比较字符串,然后拿后续的字符串依次比较,用两个索引来比较字符串是否相同,最后返回截取后的比较字符串即可。如果不理解可以看下面的图
代码详解:
class Solution {
public:string longestCommonPrefix(vector<string>& strs) {string ans=strs[0];//首先记录数组第一个元素的字符串作为对比字符串for(int i=0;i<strs.size();i++)//遍历数组{auto&s=strs[i];//用s来记录遍历到的第一个字符串int j=0,k=0;//定义两个索引一个指向对比字符串一个指向当前字符串,他们都指向这两个字符串的第一个字符while(j<ans.size()&&k<ans.size())//两个索引都不允许越界{if(ans[j]!=s[k])break;//如果两个索引匹配到的字符不相等跳出循环j++;k++;//否则继续比较}ans=ans.substr(0,j);//比较结束直接截取字符串}return ans;//返回截取后的字符串即可}
};
面经:
1. c++函数的返回值在内存中的传递过程
返回值有四种返回方法,每种方法都有不同的传递过程
(1)值返回
复制:在函数返回时,会在调用者的栈帧上创建返回值的副本。
存储:这个副本存储在寄存器或者调用者的栈上。
使用:调用者可以使用这个副本。
int add(int a, int b) {return a + b; // 返回值会被复制到调用者的栈帧或寄存器
}
(2)引用返回
不复制:函数不创建返回值的副本,而是直接返回对象的引用。
直接访问:调用者通过这个引用直接访问原始对象。
int& ref_add(int& a, int& b) {static int result = a + b; // 使用静态变量存储结果return result; // 返回引用
}
(3)指针返回
不复制:函数返回一个指向对象的指针。
间接访问:调用者通过这个指针间接访问对象。
int* ptr_add(int* a, int* b) {static int result = *a + *b; // 使用静态变量存储结果return &result; // 返回指针
}
(4)右值引用返回
这在移动语义和完美转发中非常有用,通常用于返回临时对象。
移动:返回临时对象时,其资源会被移动到调用者需要的地方。
不复制:通过移动构造函数或移动赋值运算符,避免了不必要的复制
MyClass&& createMyClass() {MyClass obj;// ...return move(obj); // 返回右值引用
}
2. 什么是虚拟内存,为什么使用虚拟内存,虚拟内存可能比物理内存大吗
- 虚拟内存是计算机系统内存管理的一个功能,它使得操作系统能够使用硬盘空间来模拟额外的RAM,即让程序认为它有比实际更多的内存可用。在虚拟内存系统中,每个程序都有一个连续的地址空间,称为虚拟地址空间
- 使用虚拟内存有几个重要的理由:
内存扩展:它允许系统运行比物理内存更大的程序。
内存保护:每个进程都有自己的虚拟地址空间,这样可以防止一个进程访问或修改另一个进程的内存,增强了系统的稳定性和安全性。
数据持久化:通过分页或交换技术,可以将不常用的内存页写入硬盘,从而腾出物理内存供其他程序使用。
提高多任务处理能力:操作系统可以为多个进程提供看似独立的内存空间,使得它们可以并发运行。
地址空间隔离:每个进程看到的内存地址都是从0开始的连续地址,这简化了程序的编写和移植。
- 虚拟内存可能比物理内存大吗?
虚拟内存的大小是可以比物理内存大的。操作系统为每个进程分配的虚拟地址空间通常远大于物理RAM的大小。例如,在32位操作系统中,一个进程通常可以访问4GB的虚拟地址空间,而在64位操作系统中,虚拟地址空间的理论上限则大得多,远远超过了当前物理内存的大小。