LeetCode刷题日记--第一天

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++;
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值