upd:12.10,陆陆续续刷了3周刷完了。比较简单 下面开始刷公司题库。
目录
剑指 Offer 32 - II. 从上到下打印二叉树 II
以后未直接A的题目每题单独写一篇BLOG—— 方便回顾(方便水博客)
直接A的题目:
剑指 Offer 03. 数组中重复的数字
遍历+mp
class Solution {
public:
int mp[100007];
int findRepeatNumber(vector<int>& nums) {
for(auto x:nums){
mp[x]++;
if(mp[x]>1)return x;
}
return nums[0];
}
};
剑指 Offer 09. 用两个栈实现队列
栈a、b。
a中的栈倒入b中后,先入后出就变成了先入先出。
所以每次入队列只需要入a中,出队列时,先把b栈推完,若b为空,则执行一次把a推到b的操作。
class CQueue {
public:
stack<int>a,b;
CQueue() {
while(!a.empty())a.pop();
while(!b.empty())b.pop();
}
void appendTail(int value) {
a.push(value);
}
int deleteHead() {
if(a.empty() && b.empty())
return -1;
if(b.empty()){
while(!a.empty()){
b.push(a.top());
a.pop();
}
}
int tmp=b.top();
b.pop();
return tmp;
}
};
/**
* Your CQueue object will be instantiated and called as such:
* CQueue* obj = new CQueue();
* obj->appendTail(value);
* int param_2 = obj->deleteHead();
*/
剑指 Offer 42. 连续子数组的最大和
简单线性dp,dp[i]:以i结尾,连续子数组的最大和。
转移比较显然。然后优化一维数组就变成了如下代码。
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int n=nums.size(),mx=nums[0],tp=nums[0];
for(int i=1;i<n;i++){
tp=max(tp+nums[i],nums[i]);
mx=max(tp,mx);
}
return mx;
}
};
/*
class Solution {
public:
int dp[100007];
int maxSubArray(vector<int>& nums) {
int n=nums.size(),mx=nums[0];
memset(dp,0,sizeof(dp));
dp[0]=nums[0];
for(int i=1;i<n;i++){
dp[i]=max(dp[i-1]+nums[i],nums[i]);
mx=max(mx,dp[i]);
}
return mx;
}
};
*/
剑指 Offer 51. 数组中的逆序对
树状数组+离散化搞一下逆序对即可(ACM入门题目竟然是hard难度)
class Solution {
public:
int c[100007],n;
void add(int x,int d){
while(x<=n){
c[x]+=d;
x+=x&(-x);
}
}
int qu(int x){
int ans=0;
while(x){
ans+=c[x];
x-=x&(-x);
}
return ans;
}
int li[100007];
int reversePairs(vector<int>& nums) {
int sz=nums.size();
for(int i=0;i<sz;i++)
li[i+1]=nums[i];
sort(li+1,li+1+sz);
n=unique(li+1,li+1+sz)-(li+1);
int ans=0;
memset(c,0,sizeof(c));
for(int i=sz-1;i>=0;i--){
int val=lower_bound(li+1,li+1+n,nums[i])-li;
ans+=qu(val-1);
add(val,1);
}
return ans;
}
};
剑指 Offer 45. 把数组排成最小的数
最优情况是:交换任意相邻两数都会使得结果变小。
我们直接排序时按照这个规则进行快排即可。
struct node{
int num,len;
}p[110];
bool cmp(node a,node b){
return (long long)a.num*pow(10,b.len) + b.num<(long long)b.num*pow(10,a.len) + a.num;
}
class Solution {
public:
string minNumber(vector<int>& nums) {
int n=nums.size();
for(int i=0;i<n;i++){
int tp=nums[i],len=0;
while(tp){
len++;
tp/=10;
}
p[i]=node{nums[i],max(1,len)};
}
sort(p,p+n,cmp);
string ans;
for(int i=0;i<n;i++)
ans+=to_string(p[i].num);
return ans;
}
};
剑指 Offer 25. 合并两个排序的链表
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
ListNode* ans = new ListNode(0);
ListNode* pr = ans;
while(l1||l2){
if(l2==NULL||(l1!=NULL && l1->val < l2->val)){
ans->next=l1;
l1=l1->next;
}else{
ans->next=l2;
l2=l2->next;
}
ans=ans->next;
}
return pr->next;
}
};
剑指 Offer 22. 链表中倒数第k个节点
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* getKthFromEnd(ListNode* head, int k) {
int num = 0;
ListNode *tp=head;
while(head){
head=head->next;
num++;
}
num-=k;
while(num){
tp=tp->next;
num--;
}
return tp;
}
};
剑指 Offer 52. 两个链表的第一个公共节点
直接模拟即可
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
int na=0,nb=0;
ListNode *ta=headA;
ListNode *tb=headB;
while(ta){
ta=ta->next;
na&