一.Array
1).第一百一十八题 Pascal's Triangle
vector.assign(n,vector<int>(1)) ; 每个放入一个0;
vector.assign(n,vector<int>(1,1)) ; 每个放入一个1;
2).第一百一十九题 Pascal's Triangle II
1.res.assign(n+1,1);
2.for(int j=n;j>=1;j--) //倒序
3).第一百六十三题 Missing Range
本题可以遍历判断两个之间的,加上开头和lower的关系,末尾和upper的关系,用两个值temp1和temp2来判断是否有“->”;
也可以用答案的想法,上限:r:num[i] || upper+1 下限:l :上一个r+1,中间缺失数值便是
4).第一百八十九题 Rotate Array
旋转,不是简单替换,swap(nums[i],nums[n - k + i])不对,自己举个例子试;
1.新建一个一模一样的数组t,nums[(i+k)%n] = t[i];
2. nums.push_back(nums[0]);nums.erase(num.begin());
5).第一百二十一题 Best Time to Buy and Sell Stock
只需要遍历一次数组,用一个变量记录之前遍历数中的最小值,然后每次计算当前值和这个最小之间的差值为利润,更新每次利润值
二 string
6).第一百五十一题 Reverse Words in a String
1.reverse(s.begin()+pre,s.begin()+i+1);这里要加1
2.多个连续空格要去掉 if (s[i] != ' ')
3.if(size!=0) s[size++]=' ';//非开头非末尾 ,j值到了末尾,i=j,跳出循环
4.s.resize(storeIndex);
7).第一百五十七题 Read N Characters Given Read4
仔细读懂题目,cur=read4(buf+res);返回的是读取个数
8).第一百五十八题 Read N Characters Given Read4 II - Call multiple times
貌似是用两个变量readPos和writePos来记录读取和写的位置,i从0到n开始循环,如果此时读和写的位置相同,那么我们调用read4函数,将结果赋给writePos,把readPos置零,如果writePos为零的话,说明buf中没有东西了,返回当前的坐标i。然后我们用内置的buff变量的readPos位置覆盖输入字符串buf的i位置,如果完成遍历,返回n ???
9).第一百六十一题 One Edit Distance
多一个或者有一个匹配不上
10).第一百六十五题 Compare Version Numbers
每一个点之前的数组存储,比较
11).第一百八十六题 Reverse Words in a String II
第一百五十一题的简化版
3.Hash
84)第一百二十七题 Word Ladder
到达用set保存dict,用map建立中间词和步数的映射,queue保存当前状态,每个字母用二十六个字母替换,dict里面有步数就加1,末尾就返回步数。
1.ch从a到z不会和之前的值重复,因为后面会有判断 m.count;
2.怎么样看出shorteset? ch从a到z,m[newword]=word++;
12)第一百三十八题 Copy List with Random Pointer
本题random指向,有可能指向的还没复制到
1.用map记录random ,复制节点 2.在map上找出每个几点的random
13)第一百四十九题 Max Points on a Line
map最好不要用double做key值,因为检索key值用的是比较,精度问题;
vector<vector<int>> points(M,vector<int>(N));//行为M,列为N
double 类型每次数值有可能不一样。比如 [[0,0],[94911151,94911150],[94911152,94911151]] 斜率一样
用一个点和其他的点算斜率,斜率一样就在一条直线上,不用算位移,点和斜率就能确定一条直线
int gcd(int a,int b){
return (b==0)?a:gcd(b,a % b); 存储除数与被除数,再除以最大公约数
}
14)第一百五十九题 Longest Substring with At Most Two Distinct Characters
m.size() >2; if(--m[s[left]]==0) m.erase(s[left]) 最左边不一定是非重复的 ;
15)第一百六十六题 Fraction to Recurring Decimal
result.insert(hmap[r],1,'('); 在hmap[r]位置前1处插入(
16)第一百七十题 Two Sum III
a.first ;a.second = m.count
17)第一百八十七题
取十个字符放进map(set)
4. DP
18)第一百一十五题 Distinct Subsequences
s为空,无匹配,值为0;T为空,s的子集空集匹配,值为1
画图二维映射,i为T,j 为S,横着看 循环外层 n,里层m,答案那种横着看比较合适
19)第一百二十题 Triangle
vector::back() 返回的是vector最后一个元素
二维动态规划 两头的 :
if(j==0) triangle[i][j] += triangle[i-1][j]; else if(j==triangle[i].size()-1) triangle[i][j] += triangle[i-1][j-1];
中间的:
triangle[i][j] += min(triangle[i-1][j-1],triangle[i-1][j]);
20)第一百二十三题 Best Time to Buy and Sell Stock III
local[i][j]: 到达第i天时最多可进行j次交易并且最后一次交易在最后一天卖出的最大利润,此为局部最优。
global[i][j]: 到达第i天时最多可进行j次交易的最大利润,此为全局最优。g:0~2 0次交易,1次交易,2次交易
local[i][j] = max(global[i-1][j-1]+max(diff,0),local[i-1][j]+diff) //local[i-1][j]+diff 前一天买入,最后一天卖出?
global[i][j] = max(local[i][j],g[i-1][j]);//最多,所以g[i-1][j]>g[i-1][j-1]
83)第一百三十二题 Palindrome Partitioning II
dp[i]=i; if (p[i][j]) dp[i]=(j==0)?0:min(dp[i],dp[j-1]+1) 注意j<=i,这样dp[i]=dp[i-1]+1可以获得
21)第一百三十九题 Word Break
for(int i=0;i<len+1;i++) for(int j=0;j<i;j++) res[j]&&dict.find(s.substr(j,i-j)!=dic.end() res[i] = true;
substr(i,j) 获得字符串s 从i开始长度为j的子串 因为res[n+1](dp[0]为空,true初始值,长度多一个)
22)第一百五十二题 Maximum Product Subarray
1.当遍历到一个正数时,此时的最大值等于之前的最大值乘以这个正数和当前正数中的较大值,此时的最小值等于之前的最小值乘以这个正数和当前正数中的较小值。
2.当遍历到一个负数时,此时的最大值等于之前的最小值乘以这个负数和当前负数中的较大值,此时的最小值等于之前的最大值乘以这个负数和当前负数中的较小值。
这次不考虑正负数,全取最大值更新 solution 4
动态规划 solution 1 之前最小值*当前值,之前最大值*当前值,当前值 这三个中取最大值
23)第一百七十四题 Dungeon Game
本题是求中间经过的最大的负值的相反数。
逆推,dp[i][j] = max(1,min(dp[i+1][j],dp[[i][j+1])-dungeon[i][j]) 当前需要的血数
24)第一百八十八题 Best Time to Buy and Sell Stock IV
k>=prices.size() : Best Time to Buy and Sell Stock III
k<prices.size(): Best Time to Buy and Sell Stock II
25)第一百九十八题 House Robber
max(num[i]+dp[i-2],dp[i-1])
5.stack
26)第一百四十四题 Binary Tree Preoder Traversal
while(!s.empty()) stack,push(root) ,s.top(),s.pop() push(root->left) push(root->right)
27)第一百四十五题 Binary Tree Postoder Traversal
答案一:t为局部根。
1.insert(res.begin(),root->val) push(left) push(right)
2.push(p->right) insert(res.begin(),p) t=s.top() p=t->left 见答案3
28)第一百五十题 Evaluate Reverse Polish Notation
本题"*", "/",在“+”,“-” 的前面,输入的时候就是,所以不用考虑算法优先级
29)第一百七十三题 Binary Search Tree Iterator
注意BST最左下角的值提取出后,其右子树比其根小
6.2p
30)第一百二十五题 Valid Palindrome
A=65,a=97 (s[left]+32-'a')%32=(s[right]+32-'a')%32
31)第一百四十一题 Linked List Cycle
快慢指针,一个跑的快,一个跑的慢,跑到环里,总会相遇,快指针多跑了环n圈。
32)第一百四十二题 Linked List Cycle II
AC:head 到环的起点 CB: 环的起点到相遇点 快指针走2,慢指针走1,快指针走的距离是慢指针的两倍
2(AC+CB)=AC+K*R+CB => AC+CB=(K-1)*R+R=> AC=(K-1)*R+BC
AC的距离等于绕环若干圈后再加上BC的距离=〉慢指针从A点出发,快指针从 B点出发,两者以速度1前进,在环的
起点相遇。
无cycle的情况下,if(!fast||!fast->next) return NULL;
49)第一百六十七题 Two Sum II
很简单
7.Depth-first Search
33)第一百零一题 Symmetric Tree
return isSymmetric(left->left,right->right) && isSymmetric(left->right,right->left)
34)第一百零四题 Maximum Depth of Binary Tree
递归 1+max(left,right)
35)第一百零五题 Construct Binary Tree from Preoder and Inorder Traversal
中序遍历和后序遍历可以唯一确定二叉树;前序遍历和中序遍历可以唯一确定二叉树
中序:24531 前序: 54131 前序根靠前排列。中序5左边左子树,右边右子树 看答案
36)第一百零六题 Construct Binary Tree from Postoder and Inorder Traversal
中序:24531 后序: 24135 后序根靠后排列。中序5左边左子树,右边右子树 看答案 right在前比left在前快
37)第一百零八题 Convert Sorted Array to Binary Search Tree
vector<int> left,right;
left.assign(nums.begin(),nums.begin()+n/2)(注意后面是结尾);
38)第一百零九题 Convert Sorted List to Binary Search Tree
会有好几种结果
1.用slow 和 fast 来找出中间值做为root,root->left = 前面的; root->right =后面的,需要有个last,fast保存 slow->next,把slow前面的尾部NULL。fast = slow->next(只有两个slow->next=null,第二个被忽略了); last->next = NULL;(否则递归的时候head后面会一直有)
2.我之前自己提交的方法。先计算出整个的长度,再左中右中序遍历建树。为什么中序遍历?head开始是左边;若为根左右,新建root,再left里再新建同一个root,走不通。
39)第一百一十题 Balanced Binary Tree
getDepth()
40)第一百一十一题 Minimum Depth of Binary Tree
if(!root->left || !root->right) 该root不是叶子节点
41)第一百一十二题 Path Sum
if(!left&&!right&&val==sum) return true;
42)第一百一十三题 Path Sum II
out.pop_back();
43)第一百一十四题 Flatten Binary Tree to Linked List
保存右子树,根的右子树为左子树,左子树的右子树为之前保存右子树(while)
44)第一百一十六题 Population Next Right Pointers in Each Node
1.递归:root->right->next = root->next? root->next->left:NULL
2.非递归:一层一层,while循环处理一层,再start=start->next 从左边开始处理下一层
45)第一百一十七题 Population Next Right Pointers in Each Node ||
递归:加个while循环,有的root->next 无子节点或只有一个节点
非递归:用一个辅助的dummy来层级遍历
46)第一百二十四题 Binary Tree Maximum Path Sum
见答案解析。对于每个节点来说,要知道经过其左子节点的path之和大还是经过右子节点的path之和大。递归函数的返回值就可以定义为以当前节点为根节点,到叶节点的最大路径之和(左还是有),然后全局路径最大值(a path)放在参数中,用结果res来表示。
return root->val + maxPathSum(root->left) + maxPathSum(root->right);返回的是所有之和
47)第一百二十九题 Sum Root to Leaf Numbers
sum=sum*10+root->val
48)第一百三十三题 Clone Graph
用map,见答案
51)第二百题 Number of Islands
一片一片用dfs+visit找