【LeetCode】栈 stack(共40题)

【20】Valid Parentheses (2018年11月28日,复习, ko)

给了一个字符串判断是不是合法的括号配对。

题解:直接stack

 1 class Solution {
 2 public:
 3     bool isValid(string s) {
 4         set<char> st{'(', '[', '{'};
 5         map<char, char> mp{{'(', ')'}, {'{', '}'}, {'[', ']'}};
 6         stack<char> stk;
 7         for (auto c : s) {
 8             if (st.find(c) != st.end()) {
 9                 stk.push(c);
10             } else {
11                 if (stk.empty()) { return false; }
12                 char t = stk.top();
13                 if (mp[t] == c) { 
14                     stk.pop(); 
15                 } else {
16                     return false;
17                 }
18             }
19         }
20         return stk.empty();
21     }
22 };
View Code

 

【42】Trapping Rain Water (2018年11月29日,需要复习,单调栈的思想)

给了一个直方图,问里面能存多少雨水。

 题解:单调栈的思想。对于数组中的每一个元素,如果栈顶元素比它小,那么当前栈顶如果左边还有柱子能围住栈顶的话,栈顶肯定有雨水。

 1 //依旧还是单调栈的思想,一个元素如果比栈顶元素大,那么它就比栈顶元素强,强的话凭啥让栈顶元素呆在栈里面?
 2 class Solution {
 3 public:
 4     int trap(vector<int>& height) {
 5         const int n = height.size();
 6         int ret = 0;
 7         stack<int> stk;
 8         for (int cur = 0; cur < n; ++cur) {
 9             while (!stk.empty() && height[stk.top()] < height[cur]) {
10                 int t = stk.top(); stk.pop();
11                 if (stk.empty()) {break;}
12                 int leftIdx = stk.top();
13                 int dis = cur - leftIdx - 1, h = min(height[leftIdx], height[cur]) - height[t];
14                 ret += dis * h;
15             }
16             stk.push(cur);
17         }
18         return ret;
19     }
20 };
View Code

 

【71】Simplify Path (2018年11月29日,复习,ko)

给了一个字符串代表 linux 的文件目录,化简这个字符串。 "." 代表当前目录, ".." 代表上一层目录。

For example,
path = "/home/", => "/home"
path = "/a/./b/../../c/", => "/c"
path = "/a/../../b/../c//.//", => "/c"
path = "/a//b////c/d//././/..", => "/a/b/c"

题解:分解字符串,然后用栈直接存。遇到 '.' 忽略, 遇到 '..' 弹出,其他往里push就行。

 1 class Solution {
 2 public:
 3     string simplifyPath(string path) {
 4         const int n = path.size();
 5         stringstream ss;
 6         ss << path;
 7         string word;
 8         stack<string> stk;
 9         while (getline(ss, word, '/')) {
10             if (word == ".") {
11                 continue;
12             } else if (word == "..") {
13                 if (!stk.empty()) { stk.pop(); }
14             } else if (!word.empty()) {
15                 stk.push(word);
16             }
17         }
18         int size = stk.size();
19         string ans;
20         for (int i = 0; i < size; ++i) {
21             ans = "/" + stk.top() + ans;
22             stk.pop();
23         }
24         if (size == 0) {
25             ans = "/";
26         }
27         return ans;
28     }
29 };
View Code

 

【84】Largest Rectangle in Histogram (2018年11月29日,单调栈,需要复习)

 

【85】Maximal Rectangle (2018年11月29日,单调栈,需要复习)

 

【94】Binary Tree Inorder Traversal (2018年11月29日,树的题目先不做)

【103】Binary Tree Zigzag Level Order Traversal (2018年11月29日,树的题目先不做)

【144】Binary Tree Preorder Traversal (2018年11月29日,树的题目先不做)

【145】Binary Tree Postorder Traversal (2018年11月29日,树的题目先不做)

 

 

【150】Evaluate Reverse Polish Notation (2018年11月29日,复习,ko)

逆波兰表达式求值。题目保证输入合法。 

Example 1:
Input: ["2", "1", "+", "3", "*"]
Output: 9

Example 2:
Input: ["10", "6", "9", "3", "+", "-11", "*", "/", "*", "17", "+", "5", "+"]
Output: 22
Explanation: 
  ((10 * (6 / ((9 + 3) * -11))) + 17) + 5
= ((10 * (6 / (12 * -11))) + 17) + 5
= ((10 * (6 / -132)) + 17) + 5
= ((10 * 0) + 17) + 5
= (0 + 17) + 5
= 17 + 5
= 22

题解:用栈实现,注意 - 和 / 的时候的顺序。

 1 class Solution {
 2 public:
 3     int evalRPN(vector<string>& tokens) {
 4         stack<int> stk;
 5         for (auto s : tokens) {
 6             if (s == "+") {
 7                 if (stk.size() >= 2) {
 8                     int a = stk.top(); stk.pop();
 9                     int b = stk.top(); stk.pop();
10                     stk.push(a+b);
11                 }
12             } else if (s == "-") {
13                 if (stk.size() >= 2) {
14                     int a = stk.top(); stk.pop();
15                     int b = stk.top(); stk.pop();
16                     stk.push(b-a);
17                 }
18             } else if (s == "*") {
19                 if (stk.size() >= 2) {
20                     int a = stk.top(); stk.pop();
21                     int b = stk.top(); stk.pop();
22                     stk.push(a*b);
23                 }
24             } else if (s == "/") {
25                 if (stk.size() >= 2) {
26                     int a = stk.top(); stk.pop();
27                     int b = stk.top(); stk.pop();
28                     stk.push(b/a);
29                 }
30             } else {
31                 stk.push(stoi(s));
32             }
33         }
34         return stk.top();
35     }
36 };
View Code

 

【155】Min Stack (2018年11月29日,水题,ko)

实现一个特殊的栈,在实现栈的基本功能的基础上,再实现返回栈中最小元素的操作。

 题解:两个栈实现,一个栈是记录真实数据,另外一个辅助栈记录最小值

 1 class MinStack {
 2 public:
 3     /** initialize your data structure here. */
 4     MinStack() {
 5         
 6     }
 7     
 8     void push(int x) {
 9         stk.push(x);
10         if (!help.empty()) {
11             help.push(min(help.top(), x));
12         } else {
13             help.push(x);
14         }
15     }
16     
17     void pop() {
18         stk.pop();
19         help.pop();
20     }
21     
22     int top() {
23         return stk.top();
24     }
25     
26     int getMin() {
27         return help.top();
28     }
29     stack<int> stk, help;
30 };
31 
32 /**
33  * Your MinStack object will be instantiated and called as such:
34  * MinStack obj = new MinStack();
35  * obj.push(x);
36  * obj.pop();
37  * int param_3 = obj.top();
38  * int param_4 = obj.getMin();
39  */
View Code

 

【173】Binary Search Tree Iterator (2018年11月29日,树的题目先不做)

 

【224】Basic Calculator (2018年11月16日,算法群)

给了一个字符串算式,里面有数字,有“+”, “-” , “ ” , 和 “(” , ")"。问算式最后结果是多少,返回int。

题解:这题两年前我好像抄的答案,今天自己写了一遍,我写的有点长,我是用了 两个栈,一个存数字,一个存符号。符号栈里面栈顶如果遇到 “+”, “-”,就把两个数搞出来作处理。如果遇到 “(” 就 push 到栈里面,如果遇到 ")"就把上一个 “(” 前面的所有符号和数字都弹出作处理。写的很长,debug了也有一会儿。 

 1 class Solution {
 2 public:
 3     int calculate(string s) {
 4         stack<int> stkNum;
 5         stack<char> stkPunc;
 6         const int n = s.size();
 7         int res = 0;
 8         string temp = "";
 9         for (int i = 0; i < n; ++i) {
10             char c = s[i];
11             if (isdigit(c)) {
12                 temp += string(1, c);
13             } else {   
14                 if (!temp.empty()) {
15                     stkNum.push(stoi(temp));
16                     temp = "";
17                 }
18                 if (c == ' ') { continue; }
19                 if (c == '(') { stkPunc.push(c); }
20                 while (stkNum.size() >= 2 && !stkPunc.empty() && stkPunc.top() != '(') {
21                     int a = stkNum.top(); stkNum.pop();
22                     int b = stkNum.top(); stkNum.pop();
23                     char p = stkPunc.top(); stkPunc.pop();
24                     int t = 0;
25                     if (p == '+') { t = a + b; }
26                     if (p == '-') { t = b - a; }
27                     stkNum.push(t);
28                 }                
29                 if (c == '+' || c == '-') { stkPunc.push(c); }
30                 if (c == ')') {
31                     while (!stkPunc.empty() && stkPunc.top() != '(' && stkNum.size() >= 2) {
32                         int a = stkNum.top(); stkNum.pop();
33                         int b = stkNum.top(); stkNum.pop();
34                         char p = stkPunc.top(); stkPunc.pop();
35                         int t = 0;
36                         if (p == '+') { t = a + b; }
37                         if (p == '-') { t = b - a; }
38                         stkNum.push(t);
39                     }
40                     if (!stkPunc.empty() && stkPunc.top() == '(') {
41                         stkPunc.pop();
42                     }
43                 }
44             }
45         }
46         if (!temp.empty()) {
47             stkNum.push(stoi(temp));
48             temp = "";
49         }
50         while (stkNum.size() >= 2 && !stkPunc.empty()) {
51             int a = stkNum.top(); stkNum.pop();
52             int b = stkNum.top(); stkNum.pop();
53             char p = stkPunc.top(); stkPunc.pop();
54             int t = 0;
55             if (p == '+') { t = a + b; }
56             if (p == '-') { t = b - a; }
57             stkNum.push(t);
58         }
59         res = stkNum.top();
60         return res;
61     }
62     /*
63     void printstk (stack<int> s1, stack<char> s2) {
64         printf("stkNum : ");
65         while (!s1.empty()) {
66             printf("%d ", s1.top());
67             s1.pop();
68         }
69         printf("\n");
70         printf("stkPunc : ");
71         while (!s2.empty()) {
72             printf("%c ", s2.top());
73             s2.pop();
74         }
75         printf("\n");
76     }
77     */
78 };
View Code

然后看了群里小伙伴们的解法基本都差不多,就是比较标准比较短的解法。我们用一个栈,存数字 也存符号。符号如果是 “+”, 就用数字 1 入栈,符号如果是 “-”,就用数字 -1 入栈。每次遇到一个新的符号,“+”,“-”,或者 “(“,”)“,我们就把原来的数字和符号处理掉再用新的符号覆盖原来的变量。

 1 class Solution {
 2 public:
 3     int calculate(string s) {
 4         stack<int> stk;
 5         string temp = "";
 6         int sign = 1, res = 0, num = 0;
 7         for (auto c : s) {
 8             if (isdigit(c)) {
 9                 temp += string(1, c);
10             } else {
11                 if (c == ' ') { continue; }
12                 num = temp.empty() ? 0 : stoi(temp);
13                 temp = "";
14                 if (c == '+' || c == '-') {
15                     res += sign * num;
16                     sign = c == '+' ? 1 : -1;
17                     num = 0;
18                 }
19                 if (c == '(') {
20                     stk.push(res);
21                     stk.push(sign);
22                     res = 0, sign = 1, num = 0;
23                 }
24                 if (c == ')') {
25                     res += sign * num;
26                     sign = stk.top(), stk.pop();
27                     num = stk.top(), stk.pop();
28                     res = sign * res + num;
29                     num = 0, sign = 1;
30                 }
31             }
32         }
33         if (!temp.empty()) {
34             res += sign * stoi(temp);
35         }
36         return res;
37     }
38 };
View Code

 

【225】Implement Stack using Queues (2018年11月29日,复习,ko)

用两个队列实现一个栈。

题解:还是思考了一下的。 

 1 class MyStack {
 2 public:
 3     /** Initialize your data structure here. */
 4     MyStack() {
 5         
 6     }
 7     
 8     /** Push element x onto stack. */
 9     void push(int x) {
10         que1.push(x);
11     }
12     
13     /** Removes the element on top of the stack and returns that element. */
14     int pop() {
15         if (que1.empty()) { swap(que1, que2); }
16         int size = que1.size();
17         for (int i = 0; i < size - 1; ++i) {
18             que2.push(que1.front());
19             que1.pop();
20         }
21         int t = que1.front(); que1.pop();
22         return t;
23     }
24     
25     /** Get the top element. */
26     int top() {
27         if (que1.empty()) { swap(que1, que2); }
28         int size = que1.size();
29         for (int i = 0; i < size - 1; ++i) {
30             que2.push(que1.front());
31             que1.pop();
32         }
33         return que1.front();
34     }
35     
36     /** Returns whether the stack is empty. */
37     bool empty() {
38         return que1.empty() && que2.empty();
39     }
40     queue<int> que1, que2;
41 };
42 
43 /**
44  * Your MyStack object will be instantiated and called as such:
45  * MyStack obj = new MyStack();
46  * obj.push(x);
47  * int param_2 = obj.pop();
48  * int param_3 = obj.top();
49  * bool param_4 = obj.empty();
50  */
View Code

 

【232】Implement Queue using Stacks (2018年11月29日,复习,ko)

 用两个队列实现一个栈。

题解:只要把握住一个原则就行。stk2 里面如果有东西,就不要往里倒。

 1 class MyQueue {
 2 public:
 3     /** Initialize your data structure here. */
 4     MyQueue() {
 5         
 6     }
 7     
 8     /** Push element x to the back of queue. */
 9     void push(int x) {
10         stk1.push(x);
11     }
12     
13     /** Removes the element from in front of queue and returns that element. */
14     int pop() {
15         int t = peek();
16         stk2.pop();
17         return t;
18     }
19     
20     /** Get the front element. */
21     int peek() {
22         if (stk2.empty()) {
23             int size = stk1.size();
24             for (int i = 0; i < size; ++i) {
25                 stk2.push(stk1.top());
26                 stk1.pop();
27             }
28         }
29         return stk2.top();
30     }
31     
32     /** Returns whether the queue is empty. */
33     bool empty() {
34         return stk1.empty() && stk2.empty();
35     }
36     stack<int> stk1, stk2;
37 };
38 
39 /**
40  * Your MyQueue object will be instantiated and called as such:
41  * MyQueue obj = new MyQueue();
42  * obj.push(x);
43  * int param_2 = obj.pop();
44  * int param_3 = obj.peek();
45  * bool param_4 = obj.empty();
46  */
View Code

 

【255】Verify Preorder Sequence in Binary Search Tree (2018年11月29日,树的题目先不做)

 

【272】Closest Binary Search Tree Value II (2018年11月29日,树的题目先不做)

 

【316】Remove Duplicate Letters (2018年11月28日,学习单调栈)

给了一个字符串,有重复的字母,要求给这个字符串去重,去重后的字符串需要是解集中字典序最小的,并且需要是原串的子序列。

Given a string which contains only lowercase letters, remove duplicate letters so that every letter appear once and only once. You must make sure your result is the smallest in lexicographical order among all possible results.

Example 1:
Input: "bcabc"
Output: "abc"
Example 2:
Input: "cbacdcbc"
Output: "acdb"

题解:一开始不会做,后来看了lintcode上有个人写的注释我就懂了,就是单调栈的思想。对于 S 中的一个字母 c,如果它已经在栈中出现了,就忽略它这次的出现。如果它没在栈中出现,那我们看栈顶,把优先级不如 c 并且以后还会出现的字母弹出去。最后把 c push 进来。https://www.lintcode.com/problem/remove-duplicate-letters/note/150821

 1 class Solution {
 2 public:
 3     string removeDuplicateLetters(string s) {
 4         vector<int> record(26, 0), st(26, 0);
 5         for (auto c : s) {
 6             record[c-'a']++;
 7         }
 8         stack<char> stk;
 9         for (auto c : s) {
10             //如果 c 已经在栈中了,就continue (说明 c 已经找到了最佳位置)
11             if (st[c-'a']) {
12                 record[c-'a']--;
13                 continue;
14             }
15             //如果栈里面有元素不如当前元素,并且它在record里面还有值(也就是说它在后续字符串中还会出现),那么就把它弹出。
16             while (!stk.empty() && stk.top() > c && record[stk.top()-'a'] >= 1) {
17                 st[stk.top()-'a'] = 0;
18                 stk.pop();
19             }
20             stk.push(c);
21             record[c-'a']--;
22             st[c-'a'] = 1;
23         }
24         int size = stk.size();
25         string ret(size, 'a');
26         for (int i = size-1; i >= 0; --i) {
27             ret[i] = stk.top();
28             stk.pop();
29         }
30         return ret;
31     }
32 };
View Code

 

【331】Verify Preorder Serialization of a Binary Tree (2018年11月29日,树的题目先不做)

 

【341】Flatten Nested List Iterator  (2018年11月29日,第一次做)

给了一个嵌套列表,返回列表中的所有值。

Example 1:
Input: [[1,1],2,[1,1]]
Output: [1,1,2,1,1]
Explanation: By calling next repeatedly until hasNext returns false, the order of elements returned by next should be: [1,1,2,1,1].

Example 2:
Input: [1,[4,[6]]]
Output: [1,4,6]
Explanation: By calling next repeatedly until hasNext returns false, the order of elements returned by next should be: [1,4,6].

题解:我用的递归解的,没用stack。

 1 /**
 2  * // This is the interface that allows for creating nested lists.
 3  * // You should not implement it, or speculate about its implementation
 4  * class NestedInteger {
 5  *   public:
 6  *     // Return true if this NestedInteger holds a single integer, rather than a nested list.
 7  *     bool isInteger() const;
 8  *
 9  *     // Return the single integer that this NestedInteger holds, if it holds a single integer
10  *     // The result is undefined if this NestedInteger holds a nested list
11  *     int getInteger() const;
12  *
13  *     // Return the nested list that this NestedInteger holds, if it holds a nested list
14  *     // The result is undefined if this NestedInteger holds a single integer
15  *     const vector<NestedInteger> &getList() const;
16  * };
17  */
18 class NestedIterator {
19 public:
20     NestedIterator(vector<NestedInteger> &nestedList) {
21         nums = getNums(nestedList);
22         idx = 0;
23         size = nums.size();
24     }
25 
26     int next() {
27         return nums[idx++];
28     }
29 
30     bool hasNext() {
31         return idx < size;
32     }
33     vector<int> getNums(vector<NestedInteger>& nestedList) {
34         vector<int> ret;
35         for (auto ele : nestedList) {
36             if (ele.isInteger()) {
37                 ret.push_back(ele.getInteger());
38             } else {
39                 vector<int> t = getNums(ele.getList());
40                 for (auto element : t) {
41                     ret.push_back(element);
42                 }
43             }
44         }
45         return ret;
46     }
47     vector<int> nums;
48     int idx = 0, size = 0;
49 };
50 
51 /**
52  * Your NestedIterator object will be instantiated and called as such:
53  * NestedIterator i(nestedList);
54  * while (i.hasNext()) cout << i.next();
55  */
View Code

 

【385】Mini Parser 

【394】Decode String 

【402】Remove K Digits 

【439】Ternary Expression Parser (2019年2月11日)

这是一个系列的题:

341 Flatten Nested List Iterator

385 Mini Parser

439 Ternary Expression Parser

 

本题是给了一个字符串作为三元表达式,求解析结果。

Input: "T?T?F:5:3"
Output: "F"

题解:看起来很难,其实还好,如果出现了连续五个字符 x?a:b 就说明这个该解析了。该解析的时候就把前面的这个整个丢进栈里面。我们用第二个字符是不是 ? 看判断前面的字符是否应该丢进栈里。

需要最早解析的字符串,其实是已经形成标准型a?X:Y的这五个连续字符。所以在第一次出现这五个连续字符之前的字符,都可以不断存进一个栈里供后续处理。

 1 class Solution {
 2 public:
 3     string parseTernary(string expression) {
 4         const int n = expression.size();
 5         stack<string> stk;
 6         string cur = "";
 7         for (int i = 0; i < n; ++i) {
 8             if (i + 1 < n && expression[i+1] == '?') {
 9                 stk.push(cur);
10                 cur = string(1, expression[i]);
11             } else {
12                 cur += string(1, expression[i]);
13                 while (cur.size() == 5) {
14                     cur = getRes(cur);
15                     if (stk.empty()) {continue;}
16                     cur = stk.top() + cur;
17                     stk.pop();
18                 }
19             }
20         }
21         return cur;
22     }
23     string getRes(string str) {
24         if (str[0] == 'T') {
25             return string(1, str[2]);
26         }
27         return string(1, str[4]);
28     }
29 };
View Code

  

【456】132 Pattern 

 

【496】Next Greater Element I (2018年11月29日,第一次做, 裸的单调栈)

给了两个数组 nums1 和 nums2, nums1 是 nums2 的子集。对于nums1中的每个元素 target,找到nums2中的对应元素的右边的第一个比 target 大的值。

题解:我先用单调栈把 nums2 的每个元素的右边第一个比它大的值求出来,存在 map 里面。然后遍历 nums1, 在 map 里面找。

 1 class Solution {
 2 public:
 3     vector<int> nextGreaterElement(vector<int>& findNums, vector<int>& nums) {
 4         unordered_map<int, int> mp;
 5         stack<int> stk;
 6         for (auto n : nums) {
 7             while (!stk.empty() && stk.top() < n) {
 8                 mp[stk.top()] = n;
 9                 stk.pop();
10             }
11             stk.push(n);
12         }
13         const int n = findNums.size();
14         vector<int> ret(n, -1);
15         for (int i = 0; i < n; ++i) {
16             if (mp.find(findNums[i]) == mp.end()) {continue;}
17             ret[i] = mp[findNums[i]];
18         }
19         return ret;
20     }
21 };
View Code

此外,本题应该可以更快,我只 beats 了 35%。

 

【503】Next Greater Element II 

【591】Tag Validator 

 

【636】Exclusive Time of Functions (2018年12月31日,昨天算法群mock的题目, 需要复习)

给了一个单个CPU任务调度的日志,形式为:function_id:start_or_end:timestamp,共有 N 个function, K 条日志,返回每个function调用的时间。一旦下一个任务开始,当前执行的任务就会被中断。

For example, "0:start:0" means function 0 starts from the very beginning of time 0. "0:end:0" means function 0 ends to the very end of time 0. 这句话要好好体会。解释了为啥碰到 end 要加一,碰到 start 不用加一。

Input:
n = 2
logs = 
["0:start:0",
 "1:start:2",
 "1:end:5",
 "0:end:6"]
Output:[3, 4]
Explanation:
Function 0 starts at time 0, then it executes 2 units of time and reaches the end of time 1. 
Now function 0 calls function 1, function 1 starts at time 2, executes 4 units of time and end at time 5.
Function 0 is running again at time 6, and also end at the time 6, thus executes 1 unit of time. 
So function 0 totally execute 2 + 1 = 3 units of time, and function 1 totally execute 4 units of time.

题解:我们用一个栈表示当前没有执行完的任务,然后两个变量cur_time,和 prev_time 表示当前日志时间,和前一条日志的时间。(注意前一条日志的时间会根据 start 和 end 决定是不是取当前的cur_time 还是 cur_time + 1)

 1 class Solution {
 2 public:
 3     vector<int> exclusiveTime(int n, vector<string>& logs) {
 4         vector<int> ret(n, 0);
 5         stack<int> stk;
 6         int prev_time = 0;
 7         for (auto & log : logs) {
 8             int taskId, cur_time; string op;
 9             split(log, taskId, op, cur_time);
10             if (op == "start") {
11                 if (!stk.empty()) {
12                     ret[stk.top()] += cur_time - prev_time;
13                 }
14                 stk.push(taskId);
15                 prev_time = cur_time;
16             } else {
17                 if (!stk.empty()) {
18                     ret[stk.top()] += cur_time - prev_time + 1;
19                     stk.pop();
20                 }
21                 prev_time = cur_time + 1;
22             }
23         }
24         return ret;
25     }
26     inline void split (const string log, int& taskId, string& op, int& time) {
27         vector<string> info(3);
28         stringstream ss(log);
29         getline(ss, info[0], ':');
30         getline(ss, info[1], ':');
31         getline(ss, info[2], ':');
32         taskId = stoi(info[0]);
33         op = info[1];
34         time = stoi(info[2]);
35         return;
36     }
37 };
View Code

 

【682】Baseball Game 

【726】Number of Atoms 

【735】Asteroid Collision 

【739】Daily Temperatures 

【770】Basic Calculator IV 

【772】Basic Calculator III 

【844】Backspace String Compare 

 

【853】Car Fleet (2019年3月11日,google tag)

有N辆车,事先知道了他们的位置和速度,他们都要去target。如果在路上后面的车追上了前面的车,那么不能超过这个车,只能保险杠挨着保险杠用前车的速度继续前进,那么这个叫做一个车队。单辆车也是一个车队,最后需要求的是总共有多少个车队到达终点。

Example 1:
Input: target = 12, position = [10,8,0,5,3], speed = [2,4,1,1,3]
Output: 3
Explanation:
The cars starting at 10 and 8 become a fleet, meeting each other at 12.
The car starting at 0 doesn't catch up to any other car, so it is a fleet by itself.
The cars starting at 5 and 3 become a fleet, meeting each other at 6.
Note that no other cars meet these fleets before the destination, so the answer is 3.

Note:
0 <= N <= 10 ^ 4
0 < target <= 10 ^ 6
0 < speed[i] <= 10 ^ 6
0 <= position[i] < target
All initial positions are different.

题解:本题我们需要解决两个问题:

(1)车的顺序,我们想先把车的先后顺序排好,可以利用当前车辆距离target的距离来排序。

(2)后面的车能不能在到达target之前追上前车。利用每辆车到达终点的剩余开车时间。如果后面一辆车的剩余开车时间小于等于前面那辆车,那么这两车一定可以合并成一个车队。

 1 class Solution {
 2 public:
 3     int carFleet(int target, vector<int>& position, vector<int>& speed) {
 4         map<int, double> mp;
 5         const int n = position.size();
 6         for (int i = 0; i < n; ++i) {
 7             mp[(target-position[i])] = (double)(target-position[i])/speed[i];
 8         }
 9         int res = 0;
10         double curTime = 0;
11         for (auto& it : mp) {
12             if (it.second > curTime) {
13                 curTime = it.second;
14                 res++;
15             }
16         }
17         return res;
18     }
19 };
View Code

 

【856】Score of Parentheses 

【880】Decoded String at Index 

【895】Maximum Frequency Stack 

 

posted @ 2019-03-11 21:49  zhangwanying  阅读(2520)  评论(0编辑  收藏  举报