思路一:
用hash表来实现。遍历数组,同时检查数组中元素是否已经在hash表中,如果在表中的话,说明元素重复,直接返回该数组元素;否则的话添加数组元素进hash表中。时间复杂度O(N),空间复杂度O(N)。
代码一:
class Solution {
public:
int findRepeatNumber(vector<int>& nums) {
unordered_map<int, int> mp;
for(int i = 0; i<nums.size();++i){
if(mp.find(nums[i]) != mp.end()){
return nums[i];
}
else{
mp[nums[i]]++;
}
}
return -1;
}
};
思路二:
先排序,然后遍历数组看是否有相邻的元素相等,有的话就说明数组中有重复的元素,返回重复的元素即可。遍历完数组即返回-1。时间复杂度:O(NlogN)
代码二:
class Solution {
public:
int findRepeatNumber(vector<int>& nums) {
sort(nums.begin(),nums.end());
for(int i = 1; i < nums.size();++i){
if(nums[i-1] == nums[i]) return nums[i-1];
}
return -1;
}
};
思路三:
遍历数组,扫描到下标为i 的元素m,比较 i和m,如果是相等的,说明该元素归位;不相等的话,将m和nums[m]比较,如果这两个数相等的话,则说明出现了重复的元素;不想等的话,则交换两个数的位置。重复这个比较、交换的过程,直到发现一个重复的数字。
时间复杂度O(N),空间复杂度O(1)。
PS:数组的长度为n,数组的元素取值范围是0~n-1
代码三:
class Solution {
public:
int findRepeatNumber(vector<int>& nums) {
for(int i = 0; i < nums.size();++i){
while(i != nums[i]){
if(nums[i] == nums[nums[i]]){
return nums[i];
}
//交换这块代码得注意
int temp= nums[i];
nums[i] = nums[temp];
nums[temp] = temp;//式子的左边不能用nums[i],因为在上一个式子中nums[i]已经变了。
}
}
return -1;
}
};
暴力法,遍历二维数组,依次判断每一个元素是否和目标相等,是的话返回true,不是的话返回false。
代码一:省略
思路二:
利用二维数组行和列依次递增的规律,从整个矩阵的右上角开始判断。找到目标元素的话就返回true;如果矩阵中的数字小于目标值(则排除掉该列);如果矩阵中的数字大于目标值(则排除该行)。行(i)初始值为0,列(j)初始值为matrix[0].size()-1,循环执行的条件是(i <=rows && j >=0)。
代码二:
class Solution {
public:
bool findNumberIn2DArray(vector<vector<int>>& matrix, int target) {
bool result = false;
if(matrix.empty()){
return result;
}
int rows = matrix.size()-1;
int cols = matrix[0].size()-1;
int i = 0, j = cols;
while(i <= rows && j >= 0){
if(target < matrix[i][j]){
j--;
}
else if(target > matrix[i][j]){
i++;
}
else{
result = true;
break;
}
}
return result;
}
};
声明一个结果字符串ans,遍历原来的字符串s,遇到空格的时候,在新字符串的位置用“%20”替代;否则直接把原字符串的字符复制到新的字符串即可。
代码一:
class Solution {
public:
string replaceSpace(string s) {
string ans;
for(int i = 0; i < s.size();++i){
if(s[i] == ' '){
ans += "%20";
}
else{
ans +=s[i];
}
}
return ans;
}
};
思路二:
代码二:
class Solution {
public:
string replaceSpace(string s) {
int oldLength = s.size();
int cnt = 0;
for(int i = 0; i < oldLength;++i){
if(s[i] == ' '){
++cnt;
}
}
int newLength = oldLength + 2 * cnt;
s.resize(newLength);
for(int i = oldLength-1,j = newLength-1; j > i && i >= 0;--i){
if(s[i] == ' '){
s[j--] = '0';
s[j--] = '2';
s[j--] = '%';
}
else{
s[j--] = s[i];
}
}
return s;
}
};
从头到尾遍历链表,依次装入栈中。出栈,将元素push_back进ans向量,直到栈为空。
代码一:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
vector<int> reversePrint(ListNode* head) {
vector<int> ans;
stack<int> st;
ListNode* ptr = head;
while(ptr){
st.push(ptr->val);
ptr = ptr->next;
}
while(!st.empty()){
ans.push_back(st.top());
st.pop();
}
return ans;
}
};
思路二:
递归,直到链表尾的nullptr返回,返回后ans.push_back元素。最终返回ans向量。
代码二:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
void helper(ListNode* node, vector<int>& ans){
if(node == nullptr){
return;
}
helper(node->next, ans);
ans.push_back(node->val);
}
public:
vector<int> reversePrint(ListNode* head) {
vector<int> ans;
helper(head, ans);
return ans;
}
};
思路:
题目意思是由二叉树的前序和中序,复原一块二叉树。根左右为(前序遍历),左右根为(中序遍历)。中序遍历是复原二叉树中的核心,遍历中序的数组,将其元素和下标存储在哈希表中,key和val依次为元素和下标的位置。从得到的前序遍历的值来new一个二叉树的节点,并将它们连接起来。PS:辅助函数的返回值是 TreeNode* 类型的。
代码:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
TreeNode* helper(vector<int>& preorder, unordered_map<int, int>& mp, int ps ,int is, int ie){
if(ps >= preorder.size() || is >= ie){
return nullptr;
}
TreeNode* root = new TreeNode(preorder[ps]);
int i = mp[preorder[ps]];
root->left = helper(preorder,mp,ps+1,is,i);
root->right = helper(preorder,mp,ps+1+(i-is),i+1,ie);
return root;
}
public:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
unordered_map<int , int> mp;
for(int i = 0; i < inorder.size();++i){
mp[inorder[i]] = i;
}
return helper(preorder,mp,0,0,inorder.size());
}
};
思路:
找到中序遍历的下一个节点。本题的树节点有指向父结点的指针,所以处理起来简单不少。二叉树的中序遍历是左根右。思路如下:
代码:
/*
struct TreeLinkNode {
int val;
struct TreeLinkNode *left;
struct TreeLinkNode *right;
struct TreeLinkNode *next;
TreeLinkNode(int x) :val(x), left(NULL), right(NULL), next(NULL) {
}
};
*/
class Solution {
public:
TreeLinkNode* GetNext(TreeLinkNode* pNode)
{
if(!pNode){
return pNode;
}
if(pNode->right){
TreeLinkNode* node = pNode->right;
while(node->left){
node = node->left;
}
return node;
}
while(pNode->next){
TreeLinkNode* root = pNode->next;
if(root->left == pNode){
return root;
}
pNode = pNode->next;
}
return nullptr;
}
};
一个数据栈,一个辅助栈实现。入队操作复杂,出队简单。这样子实现,从data栈进,从data栈出。
总是将排列好的数据放在data栈,借助temp栈来辅助实现。
入队,data中的数据为空的话直接push,否则将data 中的数据倒到temp中去,然后再push,之后将temp中的数据倒回来,即实现队列的顺序。
出队,只需看data栈,为空的话返回-1;否则取data 的栈顶元素返回。PS:一定要记得pop啊。
代码一:
class CQueue {
public:
CQueue() {
}
void appendTail(int value) {
stack<int> temp;
while (!data.empty()){
temp.push(data.top());
data.pop();
}
data.push(value);
while (!temp.empty()){
data.push(temp.top());
temp.pop();
}
}
int deleteHead() {
int val = -1;
if(!data.empty()){
val = data.top();
data.pop();
}
return val;
}
private:
stack<int> data;
};
/**
* Your CQueue object will be instantiated and called as such:
* CQueue* obj = new CQueue();
* obj->appendTail(value);
* int param_2 = obj->deleteHead();
*/
思路二:
双栈实现。入队操作复杂,出队简单。
这样子实现,队列从stack1进,从stack2出。
入队,直接push进stack1。
出队,如果stack1和stack2都为空的话,直接返回-1;stack2为空的话,将stack1的元素全部倒到stack2中;stack2不为空的话,返回栈顶元素,记得pop()。
代码二:
class CQueue {
public:
CQueue() {
}
void appendTail(int value) {
stack1.push(value);
}
int deleteHead() {
if(stack1.empty() && stack2.empty()){
return -1;
}
if(stack2.empty()){
while(!stack1.empty()){
int data = stack1.top();
stack1.pop();
stack2.push(data);
}
}
int ret = stack2.top();
stack2.pop();
return ret;
}
private:
stack<int> stack1;
stack<int> stack2;
};
/**
* Your CQueue object will be instantiated and called as such:
* CQueue* obj = new CQueue();
* obj->appendTail(value);
* int param_2 = obj->deleteHead();
*/
PS:力扣上,方法二要快一些。
class MyStack {
public:
/** Initialize your data structure here. */
MyStack() {
}
/** Push element x onto stack. */
void push(int x) {
queue<int> temp_queue;
temp_queue.push(x);
while(!_data.empty()){
temp_queue.push(_data.front());
_data.pop();
}
while(!temp_queue.empty()){
_data.push(temp_queue.front());
temp_queue.pop();
}
}
/** Removes the element on top of the stack and returns that element. */
int pop() {
int x = _data.front();
_data.pop();
return x;
}
/** Get the top element. */
int top() {
return _data.front();
}
/** Returns whether the stack is empty. */
bool empty() {
return _data.empty();
}
private:
queue<int> _data;
};
/**
* Your MyStack object will be instantiated and called as such:
* MyStack* obj = new MyStack();
* obj->push(x);
* int param_2 = obj->pop();
* int param_3 = obj->top();
* bool param_4 = obj->empty();
*/
思路二:
剑指offer思路。
代码二:
class MyStack {
public:
/** Initialize your data structure here. */
MyStack() {
}
/** Push element x onto stack. */
void push(int x) {
queue1.push(x);
topval = x;//入队的时候,每次后入的一定是栈顶元素。
}
/** Removes the element on top of the stack and returns that element. */
int pop() {
if(queue1.empty() && queue2.empty()){
return -1;
}
while(queue1.size() > 1){
topval = queue1.front();//栈顶元素弹出之后,这里要同步更新新的栈顶元素
queue1.pop();
queue2.push(topval);
}
int topval = queue1.front();
queue1.pop();
swap(queue1, queue2);//交换两个队列
return topval;
}
/** Get the top element. */
int top() {
return topval;
}
/** Returns whether the stack is empty. */
bool empty() {
return queue1.empty() && queue2.empty();
}
private:
queue<int> queue1;
queue<int> queue2;
int topval;//记录栈顶元素
};
/**
* Your MyStack object will be instantiated and called as such:
* MyStack* obj = new MyStack();
* obj->push(x);
* int param_2 = obj->pop();
* int param_3 = obj->top();
* bool param_4 = obj->empty();
*/
思路三:
一个队列也能实现。
代码三:
class MyStack {
public:
queue<int> que;
/** Initialize your data structure here. */
MyStack() {
}
/** Push element x onto stack. */
void push(int x) {
que.push(x);
}
/** Removes the element on top of the stack and returns that element. */
int pop() {
int size = que.size();
size--;
while (size--) { // 将队列头部的元素(除了最后一个元素外) 重新添加到队列尾部
que.push(que.front());
que.pop();
}
int result = que.front(); // 此时弹出的元素顺序就是栈的顺序了
que.pop();
return result;
}
/** Get the top element. */
int top() {
return que.back();
}
/** Returns whether the stack is empty. */
bool empty() {
return que.empty();
}
};
作者:carlsun-2
链接:https://leetcode-cn.com/problems/implement-stack-using-queues/solution/225-yong-dui-lie-shi-xian-zhan-liang-ge-dui-lie-sh/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
class Solution {
public:
int directs[4][2] = {{-1,0},{1,0},{0,-1},{0,1}};
bool dfs(vector<vector<char>>& board, vector<vector<bool>>& visited, string& word,int x,int y,int depth){
if(board[x][y] != word[depth]){
return false;
}
if(depth == word.size()-1){
return true;
}
visited[x][y] = true;
for(int i = 0; i < 4;++i){
int nextX = x + directs[i][0];
int nextY = y + directs[i][1];
if(nextX >=0 && nextX < board.size() && nextY >= 0 && nextY < board[0].size() && !visited[nextX][nextY]){
if(dfs(board,visited,word,nextX,nextY,depth+1)){
//printf("a\n");
return true;
}
}
}
visited[x][y] = false;
return false;
}
bool exist(vector<vector<char>>& board, string word) {
if(word == ""){
return false;
}
int rows = board.size();
int cols = board[0].size();
vector<vector<bool>> visited(rows,vector<bool>(cols,false));
for(int i = 0; i < rows;++i){
for(int j = 0; j < cols;++j){
if(dfs(board,visited,word,i,j,0)){
return true;
}
}
}
return false;
}
};