LeetCode刷题日记–第一天
第一题
647最长连续递增子序列
题目叙述:给定一个未经排序的整数数组,找到最长且连续递增的子序列,并返回该序列的长度。
题目类型:动态规划
思路一:类似于最大连续子序列和,dp[i]代表到第i个元素为止的最长递增子序列
int findLengthOfLCIS(vector<int>& nums) {
int n = nums.size();
if(n == 0)
return 0;
int dp[n];
for(int i=0; i<n; i++)
dp[i] = 1;
int ans = dp[0];
for(int i=1; i<n; i++)
{
if(nums[i] > nums[i-1])
{
dp[i] = dp[i-1] + 1;
ans = max(ans, dp[i]);
}
}
return ans;
}
注意事项:边界条件是数组长度为0,容易忽略。
思路二:贪心,因为是递增,所以从数组下标0开始,不断比较当前元素与其前一个元素,若当前元素更大,则不更新开始点,反之,更新开始点为当前元素。
第二题
996正方形数组的数目
题目叙述:给定一个非负整数数组 A,如果该数组每对相邻元素之和是一个完全平方数,则称这一数组为正方形数组。
返回 A 的正方形排列的数目。两个排列 A1 和 A2 不同的充要条件是存在某个索引 i,使得 A1[i] != A2[i]。
输入:数组A
输出:正方形数组数目
题目思路:dfs+剪枝,有重复元素的全排列且有条件的搜索,当前元素与前一个元素之和是完全平方数才继续往下搜索。
代码实现:
const int MAXN = 13;
int n;
long long ans=0;
bool visit[13] = {false};
void DFS(int index, double pre, vector<int>& A)
{
if(index == n)
{
ans++;
return;
}
for(int i=0; i<n; i++)
{
if(i>0 && A[i] == A[i-1] && !visit[i-1] || visit[i])
{
continue;
}
double sum = A[i] + pre;
double leave = sqrt(sum) - floor(sqrt(sum));
if(leave == 0.0 || index == 0)
{
visit[i] = true;
DFS(index+1, A[i], A);
visit[i] = false;
}
}
return ;
}
int numSquarefulPerms(vector<int>& A) {
n = A.size();
sort(A.begin(), A.end());
DFS(0, 0.0, A);
return ans;
}
注意事项:别忘记先排序数组,不然无法去重(5555)
第三题
题目描述:编写一个高效的算法来判断 m x n 矩阵中,是否存在一个目标值。该矩阵具有如下特性:
每行中的整数从左到右按升序排列。
每行的第一个整数大于前一行的最后一个整数。
输入:m*n矩阵
输出:是否存在目标值,存在输出true,不存在输出false
思路:遍历每行,因为每行为升序数组,比较目标值与每行最后一个元素也即最大值比较,如果比最大值大,直接跳到下一行,若比最大值小,则二分查找。
代码实现:
bool searchMatrix(vector<vector<int>>& matrix, int target) {
int m=matrix.size();
int n=matrix[0].size();
for(int i=0; i<m ;i++)
{
if(target > matrix[i][n-1])
continue;
int pos = lower_bound(matrix[i].begin(), matrix[i].end(), target) - matrix[i].begin();
if(matrix[i][pos] != target)
return false;
else
return true;
}
return false;
}
第四题
题目叙述:给定一个包含红色、白色和蓝色,一共 n 个元素的数组,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。
此题中,我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。
输入:由0/1/2组成的数组
输出:原地置换,相同值相邻,且按照0/1/2排列
思路一:单指针两次扫描,第一次单指针记录下一个0应放的位置,找到0把0放到指针位置,同样第二次把1放到指针位置
思路二:双指针,一个指针start从前往后扫记录下一个0应放的位置,一个指针en从后往前扫记录下一个2应放的位置。当扫描到的位置比en大时数组已满足要求
代码实现:
void sortColors(vector<int>& nums) {
int n = nums.size();
int start=0, en=n-1;
int i=0;
while(i<n)
{
if(en < i)
break;
if(nums[i] == 0)
{
swap(nums[start], nums[i]);
start++;
i++;
}
else if(nums[i] == 2)
{
if(nums[en] == 2)
en--;
else{
swap(nums[en], nums[i]);
en--;
}
}
else
i++;
}
}