剑指offer 试题3~10
来源:互联网 发布:淘宝 授权怎么弄啊 编辑:程序博客网 时间:2024/05/22 01:28
所有试题代码都在牛客网上提交,牛客网的数据不算很强
试题3:数组中重复的数字
牛客网上此题是输出第一个重复的数字,排序后查找会错
class Solution{public: // Parameters: // numbers: an array of integers // length: the length of array numbers // duplication: (Output) the duplicated number in the array number // Return value: true if the input is valid, and there are some duplications in the array number // otherwise false bool duplicate(int numbers[], int length, int* duplication) { bool flag = false; for(int i = 0; i < length; ++i) { while(numbers[i] != i) { if(numbers[numbers[i]] == numbers[i]) { flag = true; *duplication = numbers[i]; break; } swap(numbers[i], numbers[numbers[i]]); } if(flag) break; } return flag; }};
试题4:二维数组中的查找
从右上角开始查找。当前位置数字大于被查找数字时,那么当前位置数字所在的列剩余数字都大于被查找数字,删掉。当前位置数字小于被查找数字时,那么当前位置数字所在的行剩余数字都小于被查找数字,删掉。重复这个过程,直到二维数组删尽或者找到被查找数字
class Solution {public: bool Find(int target, vector<vector<int> > array) { int row = array.size(), col = 0; if(row != 0) col = array[0].size(); int x = 0, y = col-1; while(x < row && y >= 0) { if(array[x][y] == target) { return true; } else if(array[x][y] > target) { --y; } else { ++x; } } return false; }};
试题5:替换空格
可以先计算出替换后字符串的长度,然后用双指针的方法从后往前开始替换,注意在新字符串末尾添加’\0’
class Solution {public: void replaceSpace(char *str,int length) { int cnt = 0; int len = strlen(str); for(int i = 0; i < len; ++i) { if(str[i] == ' ') cnt += 3; else cnt += 1; } if(cnt + 1 > length) //+1是要在末尾添加一个'\0' return; str[cnt--] = '\0'; for(int i = len-1; i >= 0; --i) { if(str[i] == ' ') { str[cnt--] = '0'; str[cnt--] = '2'; str[cnt--] = '%'; } else str[cnt--] = str[i]; } }};
试题6:从尾到头打印链表
最简单的是用递归,也可以用栈,或者先正序存进vector,然后翻转vector即可
用栈:
class Solution {public: vector<int> printListFromTailToHead(ListNode* head) { vector<int> ans; stack<int> stk; ListNode *ptr = head; while(ptr != nullptr) { stk.emplace(ptr->val); ptr = ptr->next; } while(! stk.empty()) { ans.emplace_back(stk.top()); stk.pop(); } return ans; }};
翻转vector:
class Solution {public: vector<int> printListFromTailToHead(ListNode* head) { vector<int> ans; ListNode *ptr = head; while(ptr != nullptr) { ans.emplace_back(ptr->val); ptr = ptr->next; } reverse(ans.begin(), ans.end()); return ans; }};
试题7:重建二叉树
给定二叉树的先序和中序遍历,还原出二叉树。
对于一个子树的先序序列,第一个元素一定是子树的根,可以用这个元素把中序遍历划分成左右两个子树,然后递归处理
class Solution {public: TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) { int id = -1; for(int i = 0; i < vin.size(); ++i) if(vin[i] == pre[0]) { id = i; break; } if(id == -1) return nullptr; TreeNode *ptr = new TreeNode(pre[0]); if(id > 0) { vector<int> left_pre(pre.begin()+1, pre.begin()+id+1); vector<int> left_vin(vin.begin(), vin.begin() + id); ptr->left = reConstructBinaryTree(left_pre, left_vin); } if(id < vin.size() - 1) { vector<int> right_pre(pre.begin()+id+1, pre.end()); vector<int> right_vin(vin.begin()+id+1, vin.end()); ptr->right = reConstructBinaryTree(right_pre, right_vin); } return ptr; }};
试题8:二叉树的下一个节点
求二叉树中序遍历的下一个节点。
分析可知:
- 当前节点有右儿子的时候,分两种情况:其一,其右儿子没有左儿子,此时下一个节点就是其右儿子;其二,其右儿子有左儿子,那么就一直沿着左儿子往下走,走到不能走为止,此时得到的节点就是下一个节点。
- 当前节点没有右儿子,那么沿着父节点往上走,直到遇到某个点不是其父亲的左儿子位置,那么这个父节点就是要求的下一个节点。
/*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 == nullptr)//当前节点为空,下一个节点元素空 return nullptr; TreeLinkNode *ptr = nullptr; if(pNode->right != nullptr) { pNode = pNode->right; while(pNode->left != nullptr) pNode = pNode->left; ptr = pNode; } else if(pNode->next != nullptr) { while(pNode->next != nullptr && pNode->next->right == pNode) pNode = pNode->next; ptr = pNode->next; } return ptr; }};
试题9:用两个栈实现队列
- 入队:把元素直接压入栈1即可
- 出队:如果栈2空,那么把栈1中的所有元素弹出并依次压入栈2。之后从栈2弹出一个元素即可
class Solution{public: void push(int node) { stack1.emplace(node); } int pop() { int node; if(! stack2.empty()) { node = stack2.top(); stack2.pop(); } else { while(! stack1.empty()) { stack2.emplace(stack1.top()); stack1.pop(); } node = stack2.top(); stack2.pop(); } return node; }private: stack<int> stack1; stack<int> stack2;};
两个队列实现一个栈
- 压入:直接加入到队列1中
- 弹出:把队列1中元素依次出队并依次加入到队列2中,当队列1只剩最后一个元素时,就是本次要弹出的元素。最后交换队列1和队列2,stl中可以实现O(1)交换
class Solution{public: void push(int node) { queue1.push(node); } int pop() { int sz = queue1.size(); while(sz != 1) { queue2.emplace(queue1.front()); queue1.pop(); --sz; } int node = queue1.front(); queue1.pop(); queue1.swap(queue2); return node; }private: queue<int> queue1; queue<int> queue2;};
试题10:斐波那契数列
斐波那契数列:
- fib[0] = 0
- fib[1] = 1
- fib[2] = fib[1] + fib[0] = 1
- …
- fib[n] = fib[n-1] + fib[n-2]
根据公式很好写出代码
class Solution {public: int Fibonacci(int n) { if(n == 0) return 0; else if(n == 1) return 1; else { int a = 0, b = 1, c; for(int i = 2; i <= n; ++i) { c = a + b; a = b; b = c; } return c; } }};
跳台阶
一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法
分析可得:
- f[1] = 1。显然只能从起点跳1级台阶到达,故一种方案
- f[2] = f[1] + 1。可以从起点一次跳2级台阶,或者从台阶1跳1级台阶。
- f[3] = f[2] + f[1]。可以从台阶1一次跳2级台阶,或者从台阶2跳1级台阶。
- …
- f[n] = f[n-1] + f[n-2]
可以发现递推式跟斐波那契数列一样
class Solution {public: int jumpFloor(int number) { if(number == 0) return 0; if(number == 1) return 1; int a = 1, b = 1, c; for(int i = 2; i <= number; ++i) { c = a + b; a = b; b = c; } return c; }};
变态跳台阶
跟跳台阶很类似,根据上述分析过程,可以发现,这题递推式:
- f[0] = 0
- f[1] = 1
- f[2] = f[1] + 1
- f[3] = f[2] + f[1] + 1
- f[4] = f[3] + f[2] + f[1] + 1
- …
- f[n] = f[n-1] + f[n-2] + f[n-3] + … + f[2] + f[1] + 1
class Solution {public: int jumpFloorII(int number) { if(number == 0) return 0; int ans = 0, temp = 0;//temp是f[n-1] + f[n-2] + ... + f[2] + f[1] for(int i = 1; i <= number; ++i) { ans = temp + 1; temp += ans; } return ans; }};
矩形覆盖
我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形。请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?
分析如下:假设 n >= 2,那么如何得到f[n] ? 可以是从f[n-1]放一块1*2的小矩形,也可以是从f[n-2]放两块2*1的小矩形。那么递推式如下:
- f[1] = 1
- f[2] = 2
- …
- f[n] = f[n-1] + f[n-2]
跟跳台阶那题完全一样
class Solution {public: int rectCover(int number) { if(number == 0) return 0; if(number == 1) return 1; int a = 1, b = 1, c = 0; for(int i = 2; i <= number; ++i) { c = a + b; a = b; b = c; } return c; }};
阅读全文
0 0
- 剑指offer 试题3~10
- 剑指offer面试题10
- 剑指offer 面试题10
- 剑指offer面试题10
- 剑指offer面试题3
- 《剑指offer》面试题3
- 剑指offer 面试题3
- 剑指offer面试题3
- 【面试题】剑指offer 3
- 剑指offer 面试题3
- 剑指Offer(面试题8~10)
- 剑指Offer面试题10 & Leetcode191
- 读书笔记-剑指offer 面试题3
- 《剑指offer》面试题3(2)
- 剑指Offer(面试题3~5)
- 剑指Offer面试题3 & Leetcode74
- 剑指Offer试题总结
- 剑指offer 面试题
- 看到一个不错的介绍枚举的博客
- java.lang.AbstractMethodError: org.mybatis.spring.transaction.SpringManagedTransaction.getTimeout()
- 关于'JAVAC' 不是内部或外部命令的解决办法——解决WIN10系统
- OCR识别python版及python代码
- linux进程通信方式
- 剑指offer 试题3~10
- [Leetcode][python]Linked List Cycle/Linked List Cycle II
- 后期制作梦幻效果——奥顿效果(The Orton Effect)
- linux tmate 即使分享终端回话、内网穿透、ssh远程家里的linux
- Android 动态权限申请 (API23及以上的需求)
- 新路程------imx6 编译c可执行文件
- springMVC路径匹配规则
- 使用rxjava2实现验证码重新发送按钮的倒计时
- eclipse C/C++执行scanf优先于printf