剑指offer 1
来源:互联网 发布:阿里云rds逻辑备份 编辑:程序博客网 时间:2024/06/18 03:16
1 class Solution { 2 public: 3 bool Find(int target, vector<vector<int> > array) { 4 int s1 = array.size(), s2 = array[0].size(); 5 int i = s1 - 1, j = 0; 6 while (i >= 0 && j < s2) { 7 if (array[i][j] == target) { 8 return true; 9 }10 else if (array[i][j] > target) {11 i--;12 }13 else {14 j++;15 }16 }17 return false;18 }19 };
本题还可采用其他分治策略,后续补充。
2. 替换空格
请实现一个函数,将一个字符串中的空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。
分析:
插入元素如果从前向后插入的话需要O(n^2)的时间复杂度,考虑先把空格个数算出,然后从后向前复制。
代码:
1 class Solution { 2 public: 3 void replaceSpace(char *str,int length) { 4 int blankSz = 0; 5 for (int i = 0; i < length; ++i) { 6 if (str[i] == ' ') { 7 blankSz ++; 8 } 9 }10 int i = length - 1, j = length + 2 * blankSz - 1;11 while (i >= 0) {12 if (str[i] != ' ') {13 str[j] = str[i];14 j--;15 i--;16 } else {17 str[j] = '0';18 str[j - 1] = '2';19 str[j - 2] = '%';20 i--;21 j -= 3;22 }23 }24 }25 };
3. 从尾到头打印链表
输入一个链表,从尾到头打印链表每个节点的值
分析:
方法1:利用一个栈,把元素以此压栈,然后弹栈倒序输出;
方法2:利用递归(本质利用了系统的栈)
代码:
1 //方法1 2 class Solution { 3 public: 4 vector<int> printListFromTailToHead(ListNode* head) { 5 stack<int> st; 6 vector<int> result; 7 while (head != nullptr) { 8 st.push(head -> val); 9 head = head -> next;10 }11 while (!st.empty()) {12 result.push_back(st.top());13 st.pop();14 }15 return result;16 }17 };18 19 //方法220 class Solution {21 private:22 vector<int> result;23 public:24 vector<int> printListFromTailToHead(ListNode* head) {25 if (head != nullptr) {26 printListFromTailToHead(head -> next);27 result.push_back(head -> val);28 }29 return result;30 }31 };
4. 重建二叉树
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
分析:
思路就是手动做二叉树恢复的思路,在中序遍历中找到根节点的位置,然后对左右子树各自递归。注意代码的写法,helper函数的参数设计(要传起始终止位置,不要拷贝vector)和传递(搞不清楚就举例子)即可。
代码:
1 class Solution { 2 private: 3 TreeNode* helper(const vector<int>& pre, int prevStart, int prevEnd, const vector<int>& vin, int vinStart, int vinEnd) { 4 if (prevStart == prevEnd) { 5 return nullptr; 6 } 7 if (prevEnd - prevStart == 1) { 8 TreeNode* result = new TreeNode(pre[prevStart]); 9 return result;10 } 11 int rootVal = pre[prevStart];12 TreeNode* result = new TreeNode(rootVal);13 int length = 0;14 for (int i = vinStart; i < vinEnd; ++i) {15 if (vin[i] != rootVal) {16 length++;17 }18 else {19 break;20 }21 }22 result -> left = helper(pre, prevStart + 1, prevStart + length + 1, vin, vinStart, vinStart + length);23 result -> right = helper(pre, prevStart + length + 1, prevEnd, vin, vinStart + length + 1, vinEnd);24 return result;25 }26 public:27 TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {28 TreeNode* result = helper(pre, 0, pre.size(), vin, 0, vin.size());29 return result;30 }31 };
5. 用两个栈实现队列
用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。
分析:
思路1 stack1用来push, stack2用来pop(),每次pop()完把数据倒回到stack1中,保证满足队列顺序,但效率比较低;
思路2 stack1用来push, stack2用来pop(), 每次pop()前判定stack2是否为空,如果为空则将stack1中元素均倒入stack2,然后再在stack2中pop(),不空直接pop()stack2
代码:
1 //方法1 2 class Solution 3 { 4 public: 5 void push(int node) { 6 stack1.push(node); 7 } 8 9 int pop() {10 while (!stack1.empty()) {11 stack2.push(stack1.top());12 stack1.pop();13 }14 int result = stack2.top();15 stack2.pop();16 while (!stack2.empty()) {17 stack1.push(stack2.top());18 stack2.pop();19 }20 return result;21 22 }23 24 private:25 stack<int> stack1;26 stack<int> stack2;27 };28 29 //方法230 class Solution31 {32 public:33 void push(int node) {34 stack1.push(node);35 }36 37 int pop() {38 if (stack2.empty()) {39 while (!stack1.empty()) { 40 stack2.push(stack1.top());41 stack1.pop();42 }43 }44 int result = stack2.top();45 stack2.pop();46 return result;47 48 }49 50 private:51 stack<int> stack1;52 stack<int> stack2;53 };
6. 旋转数组的最小数字
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
分析:
思路1 二分搜索,用套路写就行,注意的是,其实由于更新start的条件只能在array[mid] > target时,start = mid,所以出循环后array[start]肯定不是解,可以不加那个判断;
思路2 可以用递归,注意分开两个区间的时候,有可能一个区间是非旋转的,所以递归终止条件是
if (rotateArray[0] <= rotateArray[n - 1]) { return rotateArray[0]; }
可以同时处理两种情况。
代码:
1 class Solution { 2 public: 3 int minNumberInRotateArray(vector<int> rotateArray) { 4 int start = 0, end = rotateArray.size() - 1; 5 while (start + 1 < end) { 6 int mid = start + (end - start) / 2; 7 if (rotateArray[mid] == rotateArray[0]) { 8 start = mid; 9 }10 else if (rotateArray[mid] < rotateArray[0]) {11 end = mid;12 }13 else {14 start = mid;15 }16 }17 return rotateArray[end];18 }19 };
- 剑指offer-Day.1
- 《剑指offer》系列---1
- 剑指Offer读书笔记[1]
- 剑指Offer 刷题(1)
- 剑指offer-java(1)
- 剑指offer(1)
- 【1-5】剑指offer
- 剑指offer系列--1
- 剑指offer 1-10
- 剑指offer 1
- 剑指offer(1)
- 剑指Offer读书笔记(1)
- 剑指offer题目1
- 剑指offer 练习1
- 剑指offer-1
- 剑指offer面试题1
- 剑指offer 1 复制控制
- 剑指offer 面试题1
- jquery开发:jquery事件绑定解绑机制
- 从Spark架构中透视Sparkjob
- 图片 保存 与读取
- 简单工厂模式
- leetcode— 9. Palindrome Number
- 剑指offer 1
- Android Binder机制----实现自定义的系统服务
- TCP长连接与短连接的区别
- UITextView如何添加placehoderLabel
- iOS证书详解
- 《挑战程序设计竞赛》阅读笔记二 之 ALDS1_2_C Stable Sort
- 算法导论——13.2旋转
- Linux命令
- C#169课的主要内容