文章目录
一、LeetCode-61. 旋转链表
题目
代码
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* rotateRight(ListNode* head, int k) {
if(head == nullptr) { return head; }
struct ListNode *tail, *p, *newHead;
tail = p = head;
int size = 1;
while(tail->next) {
tail = tail->next;
size++;
}
tail->next = head;
for(int i=0; i<size-k%size-1; i++) {
p = p->next;
}
newHead = p->next;
p->next = NULL;
return newHead;
}
};
思路
这题标了个中等题?
直接上步骤
- 找到尾节点并记录节点数
- 尾节点连接头节点
- p指针从head向后移动
size - k % size - 1
次 - 记录新头节点newHead
- p下一个节点指向NULL
- 返回新头节点newHead
图片演示
复杂度
时间复杂度O(n),空间复杂度O(1)
二、LeetCode-1604. 警告一小时内使用相同员工卡大于等于三次的人
题目
代码
class Solution {
public:
int tranTime(string strtime) {
int time;
time = ((strtime[0]-'0') * 10 + strtime[1]-'0') * 60 + (strtime[3]-'0') * 10 + strtime[4]-'0';
return time;
}
vector<string> alertNames(vector<string>& keyName, vector<string>& keyTime) {
int n = keyTime.size();
string lastname = " ";
vector<string> ans;
//对名称进行排序(对应时间也同等排序)
for(int i=0; i<n-1; i++) {
int k = i;
for(int j=i+1; j<n; j++) {
if(keyName[j] < keyName[k]) {
k = j;
}
}
swap(keyName[i], keyName[k]);
swap(keyTime[i], keyTime[k]);
}
//对时间进行排序
for(int i=0, j=0; i<n; j++) {
if(j == n-1 || keyName[j+1] != keyName[i]) {
sort(keyTime.begin()+i, keyTime.begin()+j+1);
i = j + 1;
}
}
//查找被警告的人
for(int i=0; i<n-2; i++) {
if(keyName[i] == keyName[i+2] && lastname != keyName[i]) {
int time1 = tranTime(keyTime[i]);
int time2 = tranTime(keyTime[i+2]);
if(time2 - time1 <= 60 && time2 - time1 > 0) {
ans.push_back(keyName[i]);
i = i + 2;
lastname = keyName[i];
}
}
}
sort(ans.begin(), ans.end());
return ans;
}
};
思路
残废代码,断断续续写了两天,过绝大部分用例,测试数据大会超时
这道题给的背景是名字无序,时间无序,但名字和时间一一对应
时间由string转成int分钟数,单写一个函数
所以先把名称和对应时间排序,再对相同名称内的时间排序,最后通过在[i, i+2]
这个区间查找人
总之写了大半天,这道题也依托答辩,资本家都不敢这么压榨员工
复杂度
时间复杂度O(n²logn),空间复杂度O(1)
三、LeetCode-1233. 删除子文件夹
题目
代码
class Solution {
public:
vector<string> removeSubfolders(vector<string>& folder) {
sort(folder.begin(), folder.end());
vector<string> ans;
ans.push_back(folder[0]);
for(int i=1; i<folder.size(); i++) {
int m = ans.back().size(); //最近父路径字符串长度
int n = folder[i].size(); //当前子路径字符串长度
if(n > m && folder[i].substr(0, m) == ans.back() && folder[i][m] == '/') {
continue;
}
ans.push_back(folder[i]);
}
return ans;
}
};
思路
LeetCode每日一题
这题做完看官解,跟官解一样
先对folder排序,这样便于找子文件
判断子路径的条件:
1、子路径长度大于父路径长度
2、前缀与父路径相等
3、前缀结束后有 ‘ / ’ 表示下一个文件
照着这三个条件,我们就可以轻松写下for循环里的判断
string::substr(int pos, int n);
为截取从pos
开始后到第n
个的子字符串
如果没有满足子路径的条件,就push进ans里
复杂度
时间复杂度O(nl logn),n为folder长度,l为文件姐的平均长度
空间复杂度O(l),截取子字符串的时候需要临时空间