每当用户执行变更文件夹操作时,LeetCode 文件系统都会保存一条日志记录。
下面给出对变更操作的说明:
"../" :移动到当前文件夹的父文件夹。如果已经在主文件夹下,则 继续停留在当前文件夹 。
"./" :继续停留在当前文件夹。
"x/" :移动到名为 x 的子文件夹中。题目数据 保证总是存在文件夹 x 。
给你一个字符串列表 logs ,其中 logs[i] 是用户在 ith 步执行的操作。
文件系统启动时位于主文件夹,然后执行 logs 中的操作。
执行完所有变更文件夹操作后,请你找出 返回主文件夹所需的最小步数
示例 1:
输入:logs = ["d1/","d2/","../","d21/","./"]
输出:2
解释:执行 "../" 操作变更文件夹 2 次,即可回到主文件夹
示例 2:
输入:logs = ["d1/","d2/","./","d3/","../","d31/"] 输出:3
示例 3:
输入:logs = ["d1/","../","../","../"]
输出:0
提示:
1 <= logs.length <= 103
2 <= logs[i].length <= 10
logs[i] 包含小写英文字母,数字,'.' 和 '/'
logs[i] 符合语句中描述的格式
文件夹名称由小写英文字母和数字组成
var minOperations = function(logs) {
let r = 0
for (let i = 0; i < logs.length; i++) {
if (logs[i] === '../') {
if (r > 0) r--
} else if (logs[i] !== './') r++
}
return r
};
function minOperations(logs: string[]): number {
let r = 0
for (let i = 0; i < logs.length; i++) {
if (logs[i] === '../') {
if (r > 0) r--
} else if (logs[i] !== './') r++
}
return r
};
class Solution {
function minOperations($logs) {
$r = 0;
foreach ($logs as $log) {
if ($log === '../') {
if ($r > 0) $r--;
} elseif ($log !== './') {
$r++;
}
}
return $r;
}
}
func minOperations(logs []string) int {
r := 0
for _, log := range logs {
if log == "../" {
if r > 0 {
r--
}
} else if log != "./" {
r++
}
}
return r
}
class Solution {
public int minOperations(String[] logs) {
int r = 0;
for (String log : logs) {
if (log.equals("../")) {
if (r > 0) r--;
} else if (log.compareTo("./") != 0) r++;
}
return r;
}
}
public class Solution {
public int MinOperations(string[] logs) {
int r = 0;
foreach (string log in logs) {
if (log == "../") {
if (r > 0) r--;
} else if (log != "./") r++;
}
return r;
}
}
int minOperations(char ** logs, int logsSize){
int r = 0;
for (int i = 0; i < logsSize; i++) {
if (strcmp(logs[i], "../") == 0) {
if (r > 0) r--;
} else if (strcmp(logs[i], "./") != 0) {
r++;
}
}
return r;
}
class Solution {
public:
int minOperations(vector<string>& logs) {
int r = 0;
for (string log : logs) {
if (log == "../") {
if (r > 0) r--;
} else if (log != "./") r++;
}
return r;
}
};
class Solution:
def minOperations(self, logs: List[str]) -> int:
r = 0
for _, log in enumerate(logs):
if log == "../":
if r > 0: r -= 1
elif log != "./": r += 1
return r
var minOperations = function(logs) {
return logs.reduce((r, log) => log === '../' && r > 0 ? r - 1 : log !== '../' && log !== './' ? r + 1 : r, 0)
};
function minOperations(logs: string[]): number {
return logs.reduce((r, log) => log == '../' && r > 0 ? r - 1 : log == '../' || log == './' ? r : r + 1, 0)
};
func minOperations(logs []string) int {
return Reduce(logs, func(r int, log string) int {
if log == "../" && r > 0 {
return r - 1
}
if log == "../" || log == "./" {
return r
}
return r + 1
}, 0)
}
func Reduce(slice []string, cb func(prev int, cur string) int, initialValue int) int {
prev := initialValue
for _, cur := range slice {
prev = cb(prev, cur)
}
return prev
}
class Solution {
function minOperations($logs) {
return array_reduce($logs, function($r, $log) {
return $log == '../' && $r > 0 ? $r - 1 : ($log != '../' && $log != './' ? $r + 1 : $r);
}, 0);
}
}
class Solution {
public int minOperations(String[] logs) { // 需累积器和组合器共同使用
return Arrays.stream(logs).reduce(0, (r, log) -> log.equals("../") && r > 0 ? r - 1 : log.equals("../") || log.equals("./") ? r : r + 1, (r0, r1) -> r0 + r1);
}
}
public class Solution {
public int MinOperations(string[] logs) {
return logs.Aggregate(0, (r, log) => log == "../" && r > 0 ? r - 1 : log != "../" && log != "./" ? r + 1 : r);
}
}
class Solution {
public:
int minOperations(vector<string>& logs) {
return accumulate(logs.begin(), logs.end(), 0, [](int r, string log) -> int {
return log == "../" && r > 0 ? r - 1 : log != "../" && log != "./" ? r + 1 : r;
});
}
};
class Solution:
def minOperations(self, logs: List[str]) -> int:
return reduce(lambda r, log : r - 1 if log == '../' and r > 0 else r + 1 if log != '../' and log != './' else r, logs, 0)
var minOperations = function(logs) {
const stack = []
for (let i = 0; i < logs.length; i++) {
if (logs[i] === '../') {
if (stack.length) stack.pop()
} else if (logs[i] !== './') stack.push(logs[i])
}
return stack.length
};
function minOperations(logs: string[]): number {
const stack = []
for (let i = 0; i < logs.length; i++) {
if (logs[i] === '../') {
if (stack.length) stack.pop()
} else if (logs[i] !== './') stack.push(logs[i])
}
return stack.length
};
class Solution {
function minOperations($logs) {
$stack = [];
foreach ($logs as $log) {
if ($log === '../') {
if (count($stack) > 0) array_pop($stack);
} elseif ($log !== './') {
$stack []= $log;
}
}
return count($stack);
}
}
func minOperations(logs []string) int {
stack := []string{}
for _, log := range logs {
if log == "../" {
if len(stack) > 0 {
stack = stack[:len(stack) - 1]
}
} else if log != "./" {
stack = append(stack, log)
}
}
return len(stack)
}
class Solution {
public int minOperations(String[] logs) {
Deque<String> stack = new ArrayDeque<String>();
for (String log : logs) {
if (log.compareTo("../") == 0) {
if (stack.isEmpty() == false) stack.pop();
} else if (log.equals("./") == false) stack.push(log);
}
return stack.size();
}
}
public class Solution {
public int MinOperations(string[] logs) {
Stack<string> stack = new Stack<string>();
foreach (string log in logs) {
if (log == "../") {
if (stack.Count > 0) stack.Pop();
} else if (log != "./") stack.Push(log);
}
return stack.Count;
}
}
int minOperations(char ** logs, int logsSize){
int* stack = malloc(sizeof(int) * 1e3);
int pos = 0;
for (int i = 0; i < logsSize; i++) {
if (strcmp(logs[i], "../") == 0) {
if (pos > 0) pos--;
} else if (strcmp(logs[i], "./") != 0) stack[pos++] = logs[i];
}
return pos;
}
class Solution {
public:
int minOperations(vector<string>& logs) {
stack<string> st;
for (string log : logs) {
if (log == "../") {
if (st.empty() == false) st.pop();
} else if (log != "./") st.push(log);
}
return st.size();
}
};
class Solution:
def minOperations(self, logs: List[str]) -> int:
stack = []
for _, log in enumerate(logs):
if log == "../":
if len(stack) > 0: stack.pop()
elif log != "./": stack.append(log)
return len(stack)