LeetCode238
给你一个整数数组 nums
,返回 数组 answer
,其中 answer[i]
等于 nums
中除 nums[i]
之外其余各元素的乘积 。
题目数据 保证 数组 nums
之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。
请不要使用除法,且在 O(n)
时间复杂度内完成此题。
示例 1:
输入: nums =[1,2,3,4]
输出:[24,12,8,6]
示例 2:
输入: nums = [-1,1,0,-3,3] 输出: [0,0,9,0,0]
提示:
2 <= nums.length <= 105
-30 <= nums[i] <= 30
- 保证 数组
nums
之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内
思路:
对于每一个数字,除了它以外的乘积就是它前面所有数字的乘积*它后面所有数字的乘积。
代码:
class Solution {
public:
vector<int> productExceptSelf(vector<int>& nums) {
int p[100001];
int q[100001];
p[0]=nums[0];
q[nums.size()-1]=nums[nums.size()-1];
for(int i=1;i<nums.size();i++)
{
p[i]=p[i-1]*nums[i];
}
for(int i=nums.size()-2;i>=0;i--){
q[i]=q[i+1]*nums[i];
}
vector<int> ans;
ans.push_back(q[1]);
for(int i=1;i<nums.size()-1;i++)
{
ans.push_back(p[i-1]*q[i+1]);
}
ans.push_back(p[nums.size()-2]);
return ans;
}
};
进阶:你可以在 O(1)
的额外空间复杂度内完成这个题目吗?( 出于对空间复杂度分析的目的,输出数组不被视为额外空间。)
思路:
就把从前往后的乘积直接存在ans里,然后从后向前遍历,用t存储从后往前的乘积。
代码:
class Solution {
public:
vector<int> productExceptSelf(vector<int>& nums) {
int len=nums.size();
vector<int> ans(len);
ans[0]=1;
for(int i=1;i<nums.size();i++)
{
ans[i]=nums[i-1]*ans[i-1];
}
int t=1;
for(int i=nums.size()-1;i>=0;i--)
{
ans[i]=ans[i]*t;
t=t*nums[i];
}
return ans;
}
};
LeetCode239
给你一个整数数组 nums
,有一个大小为 k
的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k
个数字。滑动窗口每次只向右移动一位。
返回 滑动窗口中的最大值 。
示例 1:
输入:nums = [1,3,-1,-3,5,3,6,7], k = 3 输出:[3,3,5,5,6,7] 解释: 滑动窗口的位置 最大值 --------------- ----- [1 3 -1] -3 5 3 6 7 3 1 [3 -1 -3] 5 3 6 7 3 1 3 [-1 -3 5] 3 6 7 5 1 3 -1 [-3 5 3] 6 7 5 1 3 -1 -3 [5 3 6] 7 6 1 3 -1 -3 5 [3 6 7] 7
示例 2:
输入:nums = [1], k = 1 输出:[1]
提示:
1 <= nums.length <= 105
-104 <= nums[i] <= 104
1 <= k <= nums.length
思路:
暴力过不了。
用两个数组记录从前往后的最大值和从后往前的最大值。但是这里的最大值不连续,需要每K个一组分开,也就是每k个后,最大值等于当前nums的值。
最后每K个数据比较两者的头和尾,取最大。
代码:
class Solution {
public:
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
if(k==1)return nums;
int len=nums.size();
vector<int> p(len),q(len);
vector<int> ans(len-k+1);
for(int i=0;i<len;i++)
{
if(i%k==0)p[i]=nums[i];
else p[i]=max(p[i-1],nums[i]);
}
for(int j=len-1;j>=0;j--)
{
if(j==len-1||(j+1)%k==0)q[j]=nums[j];
else q[j]=max(q[j+1],nums[j]);
}
for(int i=0;i<len-k+1;i++)
{
ans[i]=max(q[i],p[i+k-1]);
}
return ans;
}
};
LeetCode240
编写一个高效的算法来搜索 m x n
矩阵 matrix
中的一个目标值 target
。该矩阵具有以下特性:
- 每行的元素从左到右升序排列。
- 每列的元素从上到下升序排列。
示例 1:
输入: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
示例 2:
输入: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 = 20 输出:false
提示:
m == matrix.length
n == matrix[i].length
1 <= n, m <= 300
-109 <= matrix[i][j] <= 109
- 每行的所有元素从左到右升序排列
- 每列的所有元素从上到下升序排列
-109 <= target <= 109
思路:
啊啊啊我有病,我一开始用BFS写,然后同样的数据在测试数据里通过,在运行里就超时。
然后我一想,不对啊,这排序排好的用什么BFS,直接搜就好了。
代码:
class Solution {
public:
bool searchMatrix(vector<vector<int>>& matrix, int target) {
if(target==matrix[0][0])return 1;
if(target<matrix[0][0])return 0;
int i=0,j=matrix[0].size()-1;
while(i<matrix.size()&&j>=0){
if(matrix[i][j]==target)return 1;
if(matrix[i][j]>target)j--;
else i++;
}
return 0;
}
};
给你一个整数 n
,返回 和为 n
的完全平方数的最少数量 。
完全平方数 是一个整数,其值等于另一个整数的平方;换句话说,其值等于一个整数自乘的积。例如,1
、4
、9
和 16
都是完全平方数,而 3
和 11
不是。
示例 1:
输入:n =12
输出:3 解释:12 = 4 + 4 + 4
示例 2:
输入:n =13
输出:2 解释:13 = 4 + 9
提示:
1 <= n <= 104
思路:
dp
代码:
class Solution {
public:
int numSquares(int n) {
int dp[10001];
memset(dp,0,sizeof(dp));
for(int i=1;i<=n;i++)
{
dp[i]=i;
for(int j=1;i-j*j>=0;j++)
{
dp[i]=min(dp[i],dp[i-j*j]+1);
}
}
return dp[n];
}
};
LeetCode283
给定一个数组 nums
,编写一个函数将所有 0
移动到数组的末尾,同时保持非零元素的相对顺序。
请注意 ,必须在不复制数组的情况下原地对数组进行操作。
示例 1:
输入: nums =[0,1,0,3,12]
输出:[1,3,12,0,0]
示例 2:
输入: nums =[0]
输出:[0]
提示:
1 <= nums.length <= 104
-231 <= nums[i] <= 231 - 1
思路:
比较暴力,但是其实也就O(n)
遇到0就删掉,最后补上就好了。
代码:
class Solution {
public:
void moveZeroes(vector<int>& nums) {
int k=0;
int i=0;
while(i<nums.size()){
if(nums[i]==0)
{
k++;
nums.erase(nums.begin()+i);
}
else i++;
}
while(k--)
{
nums.push_back(0);
}
}
};