# 每日题目-1.6:每日一题+49+50
每日题目-1.6:每日一题+49+50
1. 每日一题71. 简化路径
题目
给你一个字符串 path ,表示指向某一文件或目录的 Unix 风格 绝对路径 (以 '/' 开头),请你将其转化为更加简洁的规范路径。
在 Unix 风格的文件系统中,一个点(.)表示当前目录本身;此外,两个点 (..) 表示将目录切换到上一级(指向父目录);两者都可以是复杂相对路径的组成部分。任意多个连续的斜杠(即,'//')都被视为单个斜杠 '/' 。 对于此问题,任何其他格式的点(例如,'...')均被视为文件/目录名称。
请注意,返回的 规范路径 必须遵循下述格式:
始终以斜杠 '/' 开头。
两个目录名之间必须只有一个斜杠 '/' 。
最后一个目录名(如果存在)不能 以 '/' 结尾。
此外,路径仅包含从根目录到目标文件或目录的路径上的目录(即,不含 '.' 或 '..')。
返回简化后得到的 规范路径 。
示例 1:
输入:path = "/home/"
输出:"/home"
解释:注意,最后一个目录名后面没有斜杠。
示例 2:
输入:path = "/../"
输出:"/"
解释:从根目录向上一级是不可行的,因为根目录是你可以到达的最高级。
示例 3:
输入:path = "/home//foo/"
输出:"/home/foo"
解释:在规范路径中,多个连续斜杠需要用一个斜杠替换。
示例 4:
输入:path = "/a/./b/../../c/"
输出:"/c"
提示:
1 <= path.length <= 3000
path 由英文字母,数字,'.','/' 或 '_' 组成。
path 是一个有效的 Unix 风格绝对路径。
思路
模拟。
s一开始结尾若没有'/'要加一个。
用name存储目录名称。
分三种情况,一是普通目录,直接加到ans结尾并加上'/'。二是name为"..",这时先删去'/',再删去上一级目录,一和二都要清空name。三是为"."或为空,此时直接清空name并continue。
最后要删除结尾多余的'/'即可得到答案。
复杂度
整个字符串之遍历一次且删除时删除的是字符串的子集,因此总的空间时间复杂度为o(n)。
代码
class Solution {
public:
string simplifyPath(string s) {
int n = s.size();
string ans, name;
if(s[n - 1] != '/') s += '/', n++;
for(int i = 0; i < n; i++){
if(ans.empty()) ans += s[i];
else if(s[i] != '/') name += s[i];
else{
// 返回上一级
if(name == ".."){
if(ans.size() > 1){
// string也可以pop
// 先除去'/'
ans.pop_back();
// 除去上一级的路径
while(ans.back() != '/') ans.pop_back();
}
name = "";
}
// 位置不变或者有重复'/'的情况
else if(name == "." || name.empty()){
name = "";
continue;
}
else{
ans += name;
ans += '/';
name = "";
}
}
}
if(ans.size() > 1 && ans.back() == '/') ans.pop_back();
return ans;
}
};
2. 49. 字母异位词分组
题目
给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。
字母异位词 是由重新排列源单词的字母得到的一个新单词,所有源单词中的字母通常恰好只用一次。
示例 1:
输入: strs = ["eat", "tea", "tan", "ate", "nat", "bat"]
输出: [["bat"],["nat","tan"],["ate","eat","tea"]]
示例 2:
输入: strs = [""]
输出: [[""]]
示例 3:
输入: strs = ["a"]
输出: [["a"]]
提示:
1 <= strs.length <= 10^4
0 <= strs[i].length <= 100
strs[i] 仅包含小写字母
思路
遍历并对每个元素的每个字符排序成为排好序的字符串,开个
各个字符异形词排序后的字符串是相同的,因此直接插入对应的vector当中即可。
还要提高速率的方法时本来插入时需要将整个字符串copy过去,但使用move之后只需要把字符串的首地址赋值过去,可以减少一次拷贝操作,提高效率。
代码
class Solution {
public:
vector> groupAnagrams(vector& strs) {
vector> ans;
if(strs.empty()) return ans;
unordered_map> ma;
for(int i = 0; i < strs.size(); i++){
string s = strs[i];
sort(s.begin(), s.end());
// 直接拷贝
// ma[s].push_back(strs[i]);
// 本来需要将整个字符串copy过去,使用move之后只需要把字符串的首地址赋值过去,可以减少一次拷贝操作,提高效率
ma[s].push_back(move(strs[i]));
}
for(auto& i: ma){
// 直接拷贝
// ans.push_back(i.second);
ans.push_back(move(i.second));
}
return ans;
}
};
3. 50. Pow(x, n)
题目
实现 pow(x, n) ,即计算 x 的 n 次幂函数(即,x^n )。
示例 1:
输入:x = 2.00000, n = 10
输出:1024.00000
示例 2:
输入:x = 2.10000, n = 3
输出:9.26100
示例 3:
输入:x = 2.00000, n = -2
输出:0.25000
解释:2^-2 = 1/2^2 = 1/4 = 0.25
-100.0 < x < 100.0
-2^31 <= n <= 2^31-1
-10^4 <= x^n <= 10^4
思路
快速幂+特判负数最大的情况。
代码
class Solution {
public:
double myPow(double x, int nn) {
if(x == 1 || nn == 0) return 1;
typedef long long ll;
double ans = 1;
// 负数取到2^-31时防止溢出转成long long
ll n = abs(ll(nn));
while(n){
if(n & 1) ans *= x;
x *= x;
n >>= 1;
}
if(nn < 0) return 1 / ans;
return ans;
}
};