Given a m x ngrid. Each cell of the grid has a sign pointing to the next cell you should visit if you are currently in this cell. The sign of grid[i][j] can be:
1 which means go to the cell to the right. (i.e go from grid[i][j] to grid[i][j + 1])
2 which means go to the cell to the left. (i.e go from grid[i][j] to grid[i][j - 1])
3 which means go to the lower cell. (i.e go from grid[i][j] to grid[i + 1][j])
4 which means go to the upper cell. (i.e go from grid[i][j] to grid[i - 1][j])
Notice that there could be some invalid signs on the cells of the grid which points outside the grid.
You will initially start at the upper left cell (0,0). A valid path in the grid is a path which starts from the upper left cell (0,0) and ends at the bottom-right cell (m - 1, n - 1) following the signs on the grid. The valid path doesn’t have to be the shortest.
You can modify the sign on a cell with cost = 1. You can modify the sign on a cell one time only.
Return the minimum cost to make the grid have at least one valid path.
Example 1:
Input: grid = [[1,1,1,1],[2,2,2,2],[1,1,1,1],[2,2,2,2]]
Output: 3
Explanation: You will start at point (0, 0).
The path to (3, 3) is as follows. (0, 0) --> (0, 1) --> (0, 2) --> (0, 3) change the arrow to down with cost = 1 --> (1, 3) --> (1, 2) --> (1, 1) --> (1, 0) change the arrow to down with cost = 1 --> (2, 0) --> (2, 1) --> (2, 2) --> (2, 3) change the arrow to down with cost = 1 --> (3, 3)
The total cost = 3.
Example 2:
Input: grid = [[1,1,3],[3,2,2],[1,1,4]]
Output: 0
Explanation: You can follow the path from (0, 0) to (2, 2).
struct Node {
int x, y, cost;
Node() :x(0), y(0), cost(0) {};
Node(int x_, int y_, int cost_) :x(x_), y(y_), cost(cost_) {};
};
class Solution {
public:
int minCost(vector<vector<int>>& grid) {
vector<vector<int>> dirs = { {0, 1}, {0, -1},{1, 0},{-1, 0} };//右左下上
int m = grid.size(), n = grid[0].size();
vector<vector<int>> flag(m, vector<int>(n, 0));
deque<Node> q;
q.push_back(Node());
int ans = 0;
while (!q.empty()) {
Node cur = q.front();
q.pop_front();
flag[cur.x][cur.y] = 1;
if (cur.x == m - 1 && cur.y == n - 1) {
ans = cur.cost;
break;
}
for (int i = 0; i < dirs.size(); ++i) {
int x = cur.x + dirs[i][0], y = cur.y + dirs[i][1];
if (x < 0 || x >= m || y < 0 || y >= n)continue;
if (flag[x][y] == 1)continue;
if (i + 1 == grid[cur.x][cur.y]) {
q.push_front(Node(x, y, cur.cost));
}
else {
q.push_back(Node(x, y, cur.cost + 1));
}
}
}
return ans;
}
};
You must use only standard operations of a queue — which means only push to back, peek/pop from front, size, and is empty operations are valid.
Depending on your language, queue may not be supported natively. You may simulate a queue by using a list or deque (double-ended queue), as long as you use only standard operations of a queue.
You may assume that all operations are valid (for example, no pop or top operations will be called on an empty stack). 225. Implement Stack using Queues
和LeetCode Implement Queue using Stacks正好相反,本题要用队列实现堆栈的效果。 队列是先进先出的,而堆栈是后进先出。如果用队列q保存数据,则要实现堆栈的pop效果时,需要获取到q的队尾元素,可以不断把q的数据从队首弹出,同时压回队尾,重复n-1次,此时队首元素就是原来的队尾元素了。堆栈的top效果和push的实现方法是类似的。 这种题目就是数据不断的倒腾。。。 完整代码如下:
class MyStack {
private:
queue<int> m_q;
public: /** Initialize your data structure here. */
MyStack() {} /** Push element x onto stack. */
void push(int x) { m_q.push(x); } /** Removes the element on top of the stack and returns that element. */
int pop()
{
int sz = m_q.size();
for (int i = 0; i < sz – 1; ++i) {
m_q.push(m_q.front());
m_q.pop();
}
int front = m_q.front();
m_q.pop();
return front;
} /** Get the top element. */
int top()
{
int sz = m_q.size(), front = m_q.front();
for (int i = 0; i < sz; ++i) {
front = m_q.front();
m_q.push(front);
m_q.pop();
}
return front;
} /** Returns whether the stack is empty. */
bool empty() { return m_q.empty(); }
};
本代码提交AC,用时3MS。
二刷。用两个queue来模拟stack,不如上面的解法好看:
class MyStack {
private:
vector<queue<int>> vq_;
int data_queue_id_;
public:
/** Initialize your data structure here. */
MyStack() {
vq_.push_back(queue<int>());
vq_.push_back(queue<int>());
data_queue_id_ = 0;
}
/** Push element x onto stack. */
void push(int x) {
vq_[data_queue_id_].push(x);
}
/** Removes the element on top of the stack and returns that element. */
int pop() {
int another_id = 1 - data_queue_id_;
int last_data = 0;
while (!vq_[data_queue_id_].empty()) {
last_data = vq_[data_queue_id_].front();
vq_[data_queue_id_].pop();
if (!vq_[data_queue_id_].empty()) {
vq_[another_id].push(last_data);
}
}
swap(another_id, data_queue_id_);
return last_data;
}
/** Get the top element. */
int top() {
int another_id = 1 - data_queue_id_;
int last_data = 0;
while (!vq_[data_queue_id_].empty()) {
last_data = vq_[data_queue_id_].front();
vq_[data_queue_id_].pop();
vq_[another_id].push(last_data);
}
swap(another_id, data_queue_id_);
return last_data;
}
/** Returns whether the stack is empty. */
bool empty() {
return vq_[data_queue_id_].empty();
}
};
You must use only standard operations of a stack — which means only push to top, peek/pop from top, size, and is empty operations are valid.
Depending on your language, stack may not be supported natively. You may simulate a stack by using a list or deque (double-ended queue), as long as you use only standard operations of a stack.
You may assume that all operations are valid (for example, no pop or peek operations will be called on an empty queue). 232. Implement Queue using Stacks
class MyQueue {
private:
stack<int> stk1, stk2; // 输入来源1,2,3,stk1从栈底到栈顶的顺序是1,2,3,stk2从栈底到栈顶的顺序是3,2,1
public: /** Initialize your data structure here. */
MyQueue() {} /** Push element x to the back of queue. */
void push(int x)
{
while (!stk2.empty()) {
stk1.push(stk2.top());
stk2.pop();
}
stk1.push(x);
} /** Removes the element from in front of queue and returns that element. */
int pop()
{
while (!stk1.empty()) {
stk2.push(stk1.top());
stk1.pop();
}
int top = stk2.top();
stk2.pop();
return top;
} /** Get the front element. */
int peek()
{
while (!stk1.empty()) {
stk2.push(stk1.top());
stk1.pop();
}
return stk2.top();
} /** Returns whether the queue is empty. */
bool empty() { return stk1.empty() && stk2.empty(); }
};
class MyQueue {
private:
stack<int> stk1, stk2;
void adjust()
{
while (!stk1.empty()) {
stk2.push(stk1.top());
stk1.pop();
}
}
public: /** Initialize your data structure here. */
MyQueue() {} /** Push element x to the back of queue. */
void push(int x) { stk1.push(x); } /** Removes the element from in front of queue and returns that element. */
int pop()
{
if (stk2.empty())
adjust();
int ans = stk2.top();
stk2.pop();
return ans;
} /** Get the front element. */
int peek()
{
if (stk2.empty())
adjust();
int ans = stk2.top();
return ans;
} /** Returns whether the queue is empty. */
bool empty() { return stk1.empty() && stk2.empty(); }
};