剑指Offer 04 二维数组的查找
方法:右上角开始查看(奇技淫巧)需要注意前提 数组的排序!
- 复杂问题 具体化! 寻找规律
class Solution { public: bool findNumberIn2DArray(vector<vector<int>>& matrix, int target) { bool found=false; if(matrix.size()!=0){ int row=0,rows=matrix.size(); int column,columns=matrix[0].size(); column=columns-1; while(row<rows && column>=0) { if(matrix[row][column]==target) { found=true; break; } if(matrix[row][column]>target) { --column; } else{ ++row; } } } return found; } };
剑指Offer 5 替换空格
方法1:新数组直接遍历,遇到空格 替换就行
class Solution { public: string replaceSpace(string s) { string res; int n=s.length(); for(int i=0;i<n;++i) { if(s[i]==' ') { res+="%20"; } else { res+=s[i]; } } return res; } };
方法2:原数组O(n)复杂度,双指针从后往前
class Solution { public: string replaceSpace(string s) { //原数组扩展,O(n)的复杂度 if(s.length()==0) return s; int originalLength=0; int numberOfBlank=0; int i=0; while(s[i]!='\0') { ++originalLength; if(s[i]==' ') { ++numberOfBlank; } ++i; } int newLength = originalLength+numberOfBlank*2; s.resize(newLength); int indexOfOriginal=originalLength; int indexOfNew=newLength; while(indexOfOriginal>=0 && indexOfNew>indexOfOriginal) { if(s[indexOfOriginal]==' ') { s[indexOfNew--]='0'; s[indexOfNew--]='2'; s[indexOfNew--]='%'; } else { s[indexOfNew--]=s[indexOfOriginal]; } --indexOfOriginal; } return s; } };
剑指Offer 6 从尾到头打印链表
方法1:用栈 stack
方法2:递归! 很简单 (递归本质上是一个栈结构!)
/** * 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) { if(!head) return {}; vector<int> a=reversePrint(head->next); a.push_back(head->val); return a; } };
剑指Offer 07 重建二叉树
方法:递归 挺难理解的!
class Solution: def buildTree(self, preorder: List[int], inorder: List[int]) -> TreeNode: def recur(root, left, right): if left > right: return # 递归终止 node = TreeNode(preorder[root]) # 建立根节点 i = dic[preorder[root]] # 划分根节点、左子树、右子树 node.left = recur(root + 1, left, i - 1) # 开启左子树递归 node.right = recur(i - left + root + 1, i + 1, right) # 开启右子树递归 return node # 回溯返回根节点 dic, preorder = {}, preorder for i in range(len(inorder)): dic[inorder[i]] = i return recur(0, 0, len(inorder) - 1) 作者:jyd 链接:https://leetcode-cn.com/problems/zhong-jian-er-cha-shu-lcof/solution/mian-shi-ti-07-zhong-jian-er-cha-shu-di-gui-fa-qin/ 来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
连续AC三道二叉树的题
前序遍历,中序遍历,和后续遍历(算法书看的好,这块敲起来也快,注意引用res)
定义上的递归实现
class Solution { public: void inorder(TreeNode* root, vector<int>& res) { if (!root) { return; } //修改这里的顺序即可 inorder(root->left, res); res.push_back(root->val); inorder(root->right, res); } vector<int> inorderTraversal(TreeNode* root) { vector<int> res; inorder(root, res); return res; } };
如果需要迭代实现,那么即是显式的把这个栈用上,本质上是一样的
剑指Offer 9 用两个栈实现队列
只能说是奇技淫巧 妙不可言!
大致如下,队尾存进stack1,队头相当于在stack2!
class CQueue { public: stack<int> s1; stack<int> s2; CQueue() { } void appendTail(int value) { s1.push(value); } int deleteHead() { if(s2.size()==0) { while(s1.size()!=0) { int temp=s1.top(); s1.pop(); s2.push(temp); } } if(s2.size()==0) return -1; int res=s2.top(); s2.pop(); return res; } }; /** * Your CQueue object will be instantiated and called as such: * CQueue* obj = new CQueue(); * obj->appendTail(value); * int param_2 = obj->deleteHead(); */