Leetcode-第7场双周赛

1165.单行键盘

题目描述

我们定制了一款特殊的力扣键盘,所有的键都排列在一行上。

我们可以按从左到右的顺序,用一个长度为 26 的字符串 keyboard (索引从 0 开始,到 25 结束)来表示该键盘的键位布局。

现在需要测试这个键盘是否能够有效工作,那么我们就需要个机械手来测试这个键盘。

最初的时候,机械手位于左边起第一个键(也就是索引为 0 的键)的上方。当机械手移动到某一字符所在的键位时,就会在终端上输出该字符。

机械手从索引 i 移动到索引 j 所需要的时间是 |i - j|

当前测试需要你使用机械手输出指定的单词 word,请你编写一个函数来计算机械手输出该单词所需的时间。

示例 1:

1
2
3
4
5
输入:keyboard = "abcdefghijklmnopqrstuvwxyz", word = "cba"
输出:4
解释:
机械手从 0 号键移动到 2 号键来输出 'c',又移动到 1 号键来输出 'b',接着移动到 0 号键来输出 'a'。
总用时 = 2 + 1 + 1 = 4.

示例 2:

1
2
输入:keyboard = "pqrstuvwxyzabcdefghijklmno", word = "leetcode"
输出:73

提示:

  • keyboard.length == 26
  • keyboard 按某种特定顺序排列,并包含每个小写英文字母一次。
  • 1 <= word.length <= 10^4
  • word[i] 是一个小写英文字母
解法

1.扫描keyboard 利用map存储每个字母的位置

2.扫描word得到距离

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Solution {
public:
int calculateTime(string keyboard, string word) {
map<char,int> m;
int i;
for(i=0;i<keyboard.size();i++)
{
m[keyboard[i]]=i;
}
int time=0;
int j=0;
for(i=0;i<word.size();i++)
{
time+=abs(j-m[word[i]]);
j=m[word[i]];
}
return time;
}
};

1166.设计文件系统

题目描述

你需要设计一个能提供下面两个函数的文件系统:

  • create(path, value): 创建一个新的路径,并尽可能将值 value 与路径 path 关联,然后返回 True。如果路径已经存在或者路径的父路径不存在,则返回 False
  • get(path): 返回与路径关联的值。如果路径不存在,则返回 -1

“路径” 是由一个或多个符合下述格式的字符串连接起来形成的:在 / 后跟着一个或多个小写英文字母。

例如 /leetcode/leetcode/problems 都是有效的路径,但空字符串和 / 不是有效的路径。

好了,接下来就请你来实现这两个函数吧!(请参考示例以获得更多信息)

示例 1:

1
2
3
4
5
6
7
8
9
10
输入: 
["FileSystem","create","get"]
[[],["/a",1],["/a"]]
输出:
[null,true,1]
解释:
FileSystem fileSystem = new FileSystem();

fileSystem.create("/a", 1); // 返回 true
fileSystem.get("/a"); // 返回 1

示例 2:

1
2
3
4
5
6
7
8
9
10
11
12
13
输入: 
["FileSystem","create","create","get","create","get"]
[[],["/leet",1],["/leet/code",2],["/leet/code"],["/c/d",1],["/c"]]
输出:
[null,true,true,2,false,-1]
解释:
FileSystem fileSystem = new FileSystem();

fileSystem.create("/leet", 1); // 返回 true
fileSystem.create("/leet/code", 2); // 返回 true
fileSystem.get("/leet/code"); // 返回 2
fileSystem.create("/c/d", 1); // 返回 false 因为父路径 "/c" 不存在。
fileSystem.get("/c"); // 返回 -1 因为该路径不存在。

提示:

  • 对两个函数的调用次数加起来小于等于 10^4
  • 2 <= path.length <= 100
  • 1 <= value <= 10^9
解法

模拟存放,map存已经生成的路径

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
class FileSystem {
private:
map<string,int> F;
public:
FileSystem() {

}

bool create(string path, int value) {
string t;
int n=path.length();
int i;
for(i=0;i<n;i++)
{
t+=path[i];
for(i++;i<n;i++)
{
if(path[i]=='/')break;
t+=path[i];
}
if(i!=n&&!F.count(t)) return false;
i--;
}
if(F.count(t)) return false;
F[t]=value;
return true;
}

int get(string path) {
if(!F.count(path))
return -1;
else return F[path];
}
};

/**
* Your FileSystem object will be instantiated and called as such:
* FileSystem* obj = new FileSystem();
* bool param_1 = obj->create(path,value);
* int param_2 = obj->get(path);
*/

1167.连接棒材的最低费用

题目描述

为了装修新房,你需要加工一些长度为正整数的棒材 sticks

如果要将长度分别为 XY 的两根棒材连接在一起,你需要支付 X + Y 的费用。 由于施工需要,你必须将所有棒材连接成一根。

返回你把所有棒材 sticks 连成一根所需要的最低费用。注意你可以任意选择棒材连接的顺序。

示例 1:

1
2
3
输入:sticks = [2,4,3]
输出:14
解释:先将 2 和 3 连接成 5,花费 5;再将 5 和 4 连接成 9;总花费为 14。

示例 2:

1
2
输入:sticks = [1,8,3,5]
输出:30

提示:

  • 1 <= sticks.length <= 10^4
  • 1 <= sticks[i] <= 10^4
解法

思路是huffman树,每次取数组的最小值和次小值,用优先级队列快速实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Solution {
public:
int connectSticks(vector<int>& sticks) {
priority_queue<int,vector<int>,greater<int>> que;
int n=sticks.size();
int sum=0;
for(int i=0;i<n;i++)
que.push(sticks[i]);
while(!que.empty()&&que.size()>=2)
{
int x=que.top();que.pop();
int y=que.top();que.pop();
int z=x+y;
sum+=z;
que.push(z);
}
return sum;
}
};