每日六题-剑指offer(五)
2018-04-02 23:27
190 查看
剑指offer之每日六题
1.复杂链表的复制2.二叉树与双向链表
3.字符串的排列
4.数组中出现次数超过一半的数字
5.最小的第k个数
6.连续子数组的最大和
1.复杂链表的复制
/** 先留着 **/ /* class Solution { public: RandomListNode* Clone(RandomListNode* pHead) { if (!pHead) return NULL; nodeClone(pHead); connectRandom(pHead); return reconnect(pHead); } //[1]复制结点,插入到原结点后方 void nodeClone(RandomListNode *head) { RandomListNode *pNode = head; while (pNode != NULL) { RandomListNode *pClone = new RandomListNode(pNode->label); pClone->next = pNode->next; pNode->next = pClone; pNode = pClone->next; } } //[2]还原新结点的random指针 void connectRandom(RandomListNode *head) { RandomListNode *pNode = head; while (pNode != NULL) { RandomListNode *pClone = pNode->next; if (pNode->random) { pClone->random = pNode->random->next; } pNode = pClone->next; } } //[3]拆分 RandomListNode *reconnect(RandomListNode *head) { RandomListNode *pNode = head; RandomListNode *result = head->next; while (pNode != NULL) { RandomListNode *pClone = pNode->next; pNode->next = pClone->next; pNode = pNode->next; if (pNode != NULL) pClone->next = pNode->next; } return result; } };
2.二叉树与双向链表
/** 二叉搜索树的中序遍历是从大到小的,然后记录当前节点和上一个节点pre,更新每个节点的指向,使其变成一个双向链表,递归和非递归都在这了 **/ class Solution { public: TreeNode* pre=nullptr; TreeNode* p=nullptr; void ConvertSub(TreeNode* root){ if(root==nullptr) return ; ConvertSub(root->left); if(!pre){ pre=root; p=root; } else{ pre->right=root; root->left=pre; pre=root; } ConvertSub(root->right); } TreeNode* Convert(TreeNode* root) { ConvertSub(root); return p; /*if(root==nullptr) return NULL; stack<TreeNode*> s; TreeNode* p=root; TreeNode* pre=NULL; while(p!=nullptr||!s.empty()){ while(p!=nullptr){ s.push(p); p=p->left; } p=s.top(); s.pop(); if(!pre){ root=p; pre=root; } else{ pre->right=p; p->left=pre; pre=p; } p=p->right; } return root; */ } };
3.字符串的排列组合
/** 我用的是传说中的交换法,将当前指针指向的值和后面的交换,递归回溯,然后用set去重排序,最后把结果保存起来 **/ class Solution { public: set<string> res; void get_ans(string str,int begin){ if(begin==str.length()-1) res.insert(str); else{ for(int i=begin;i<str.length();i++){ swap(str[begin],str[i]); get_ans(str,begin+1); swap(str[begin],str[i]); } } } vector<string> Permutation(string str) { vector<string> ans; if(str.length()==0) return ans; get_ans(str,0); set<string>::iterator p; for(p=res.begin();p!=res.end();p++){ ans.push_back(*p); } return ans; } };
4.数组中次数超过一半的数字
/** map的基本用法 **/ class Solution { public: map<int,int> m; int MoreThanHalfNum_Solution(vector<int> numbers) { for(int i=0;i<numbers.size();i++){ if(++m[numbers[i]]>(numbers.size()/2)) return numbers[i]; } return 0; } };
5.最小的k个数
/** 排序,保存 **/ class Solution { public: vector<int> GetLeastNumbers_Solution(vector<int> input, int k) { vector<int> res; if(input.empty()||k>input.size()) 4000 return res; sort(input.begin(),input.end()); for(int i=0;i<k;i++) res.push_back(input[i]); return res; } };
6.连续子树组的最大和
/** (盗版过来的,侵删) 使用动态规划 F(i):以array[i]为末尾元素的子数组的和的最大值,子数组的元素的相对位置不变 F(i)=max(F(i-1)+array[i] , array[i]) res:所有子数组的和的最大值 res=max(res,F(i)) 如数组[6, -3, -2, 7, -15, 1, 2, 2] 初始状态: F(0)=6 res=6 i=1: F(1)=max(F(0)-3,-3)=max(6-3,3)=3 res=max(F(1),res)=max(3,6)=6 i=2: F(2)=max(F(1)-2,-2)=max(3-2,-2)=1 res=max(F(2),res)=max(1,6)=6 i=3: F(3)=max(F(2)+7,7)=max(1+7,7)=8 res=max(F(2),res)=max(8,6)=8 i=4: F(4)=max(F(3)-15,-15)=max(8-15,-15)=-7 res=max(F(4),res)=max(-7,8)=8 以此类推 最终res的值为8 **/ class Solution { public: int FindGreatestSumOfSubArray(vector<int> array) { int res = array[0]; int maxn= array[0]; for (int i = 1; i < array.size(); i++) { maxn=max(maxn+array[i], array[i]); res=max(maxn, res); } return res; } };
相关文章推荐
- 每日六题-剑指offer(二)
- 每日六题-剑指offer(三)
- 剑指offer每日一刷-2017年11月12日
- 剑指offer每日一刷-2017年11月14日
- 剑指Offer每日6题(JavaScript版)--第二天
- 剑指offer每日一刷-2017年11月19日
- 每日六题-剑指offer(四)
- 【每日一道算法题】
- 每日英语 词汇
- 每日一个知识点7 2014/6/10
- 剑指offer 练习六(Java版)
- Visual Studio 2008 每日提示(八)
- 剑指OFFER之第一个只出现一次的字符(九度OJ1283)
- 每日一题(36)—— 什么是预编译 , 何时需要预编译?
- Visual Studio 2008 每日提示(十二)
- [每日app二]月入60万多嘛?单词锁屏的潜力!
- 每日随笔记录2016-05-13_1
- 每日英语阅读(三十五)
- Visual Studio 2008 每日提示(十八)
- CSS3每日一练之内容处理-插入文字