04. 二维数组中的查找
在一个 n * m 的二维数组中,每一行都按照从左到右 非递减 的顺序排序,每一列都按照从上到下 非递减 的顺序排序。请完成一个高效的函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
示例:
现有矩阵 matrix 如下:
[
[1, 4, 7, 11, 15],
[2, 5, 8, 12, 19],
[3, 6, 9, 16, 22],
[10, 13, 14, 17, 24],
[18, 21, 23, 26, 30]
]
给定 target = 5,返回 true。
给定 target = 20,返回 false。
class Solution {
public:
bool findNumberIn2DArray(vector<vector<int>>& matrix, int target) {
//O(M+N)
int n=matrix.size();
if(n==0) return false;
int m=matrix[0].size();
if(m==0) return false;
int i=0,j=m-1;
while(i<=n-1 && j>=0){
if(matrix[i][j]>target) j--;
else if(matrix[i][j]<target) i++;
else return true;
}
return false;
}
};
bool findNumberIn2DArray(vector<vector<int>>& matrix, int target) {
//二分O(NlogM)
int n=matrix.size();
if(n==0) return false;
int m=matrix[0].size();
if(m==0) return false;
for(int i=0;i<n;i++){
int l=0,r=m-1;
if(matrix[i][l]<=target && matrix[i][r]>=target) {
//二分
while(l<r){
int mid=(l+r)>>1;
if(matrix[i][mid]>target) r=mid;
else if(matrix[i][mid]<target) l=mid+1;
else return true;
}
if(matrix[i][l]==target) return true;
}
}
return false;
}
14- I. 剪绳子
给你一根长度为 n 的绳子,请把绳子剪成整数长度的 m 段(m、n都是整数,n>1并且m>1),每段绳子的长度记为 k[0],k[1]…k[m-1] 。请问 k[0]k[1]…*k[m-1] 可能的最大乘积是多少?例如,当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18。
示例 1:
输入: 2
输出: 1
解释: 2 = 1 + 1, 1 × 1 = 1
示例 2:
输入: 10
输出: 36
解释: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36
class Solution {
public:
int cuttingRope(int n) {
//dp[i]: 长度为i的绳子剪成m段的最大乘积
//dp[i]=max(j(i-j),dp[i-j]*j):(长度为i-j的段不裁,长度为i-j的段继续裁)
vector <int> dp(n + 1);
dp[1] = 1;
dp[2] = 1;
for(int i=3;i<=n;i++){
for(int j=i-1;j>0;j--){
dp[i]=max(dp[i],max(j*(i-j),j*dp[i-j]));
}
}
return dp[n];
}
};
贪心:证明
结论:当所有绳段长度相等时,乘积最大。② 最优的绳段长度为 33
class Solution {
public int cuttingRope(int n) {
if(n < 4){
return n - 1;
}
int res = 1;
while(n > 4){
res *= 3;
n -= 3;
}
return res * n;
}
}
32 - I. 从上到下打印二叉树
从上到下打印出二叉树的每个节点,同一层的节点按照从左到右的顺序打印。
例如:
给定二叉树: [3,9,20,null,null,15,7],
返回:
[3,9,20,15,7]
class Solution {
public:
vector<int> levelOrder(TreeNode* root) {
//bfs
vector<int> p;
queue<TreeNode*> q;
q.push(root);
while(!q.empty()){
auto n=q.front();q.pop();
if(n){
p.push_back(n->val);
if(n->left) q.push(n->left);
if(n->right) q.push(n->right);
}
}
return p;
}
};
32 - II. 从上到下打印二叉树 II
从上到下按层打印二叉树,同一层的节点按从左到右的顺序打印,每一层打印到一行。
例如:
给定二叉树: [3,9,20,null,null,15,7],
返回其层次遍历结果:
[
[3],
[9,20],
[15,7]
]
每次队列中存储的就是一层的结点的数量。所以要使用q.size()
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> p;
if (!root) {
return p;
}
queue<TreeNode*> q;
q.push(root);
while(!q.empty()){
p.push_back(vector <int> ());
int cur_q_size=q.size();
for(int i=1;i<=cur_q_size;i++){
auto no=q.front();q.pop();
p.back().push_back(no->val);
if(no->left) q.push(no->left);
if(no->right) q.push(no->right);
}
}
return p;
}
};
ret.push_back(vector ()); 在结果数组(ret, 二维)中添加一个新的数组(一维)用于保存每一层的节点 ret.back().push_back(node->val);获取结果数组(ret, 二维)中最后一个数组(一维,保存当前层节点的数组),并在该数组中添加节点
16. 数值的整数次方
实现 pow(x, n) ,即计算 x 的 n 次幂函数(即,xn)。不得使用库函数,同时不需要考虑大数问题。
class Solution {
public:
double multi(double x, long long int N){
double res=1, con=x;
while(N > 0){
if(N%2 == 1){
res *= con;
}
con *= con;
N /= 2;
}
return res;
}
double myPow(double x, int n) {
long long int N=n;
if(N>0) return multi(x,N);
else return 1.00/(multi(x,-N));
}
};
递归
class Solution {
public:
double quick_multi(double x, long long int N){
if(N==0) return 1.0;
double y=quick_multi(x,N/2);
return N%2==0? y*y:y*y*x;
}
double myPow(double x, int n) {
long long int N=n;
if(N>0) return quick_multi(x,N);
else return 1.00/(quick_multi(x,-N));
}
};