leetcode记录 31-60

31 Next Permutation

STL源码剖析中就有这道题的思路

32 longest valid parentheses (hard)

思路1:用stack实现。当i为左括号时,将i入栈。如果i为右括号时:栈顶元素对应的s为左括号,记录accout=i-stack.top();如果为左括号,则讲i入栈

思路2:动态规划
初始化:dp[i]=0 i=0-len-1
从i=len-2开始 if(dp[i]==’(’ && i+dp[i+1]+1

int longestValidParentheses(string s) {
        int len = s.length();
        if(len<2)
          return 0;
        int max = 0;
        int *dp = new int[len];
        for(int k = 0;k<len;k++)//把辅助数组清空,存储为0
         dp[k] = 0;
        for(int i = len-2;i>=0;i--)
        {
          if(s[i] == '(')//只对左括号处理,右括号在数组中存储为0
          {
            int j = i+1+dp[i+1];//计算与当前左括号匹配的右括号的位置。可能存在也可能不存在
            if(j<len && s[j] == ')')//确保位置不能越界
            {
              dp[i] = dp[i+1] + 2;//找到了相匹配的右括号,当前数组中存储的最长长度是它后一个位置加2,后一个位置可能存储长度是0
              if(j+1<len)//这是连接两个子匹配的关键步骤
                dp[i] += dp[j+1];//在j的后面可能已经存在连续的匹配,要记得加上。dp[j+1]存储了以j+1开始的匹配
            }
            if(dp[i]>max)
              max = dp[i];//更新最长长度
          }

        }
        return max;
    }

33 search in rotated sorted array(hard)

这道题剑指offer出现过类似的题目,这道题是个简化的版本,不考虑元素存在重复的情况

思路,用二值查找法

int search(vector<int>&A,int target)
    {
        int n=A.size();
        int low=0;
        int high=n-1;
        while(low<=high){
            int mid=low+(high-low)/2;
            if(A[mid]==target)return mid;
            if(A[mid]<A[high])
            {
                if(A[mid]<target && A[high]>=target )
                    low=mid+1;
                else
                    high=mid-1;
            }
            else
            {
                if(A[mid]>target &&A[low]<=target)
                    high=mid-1;
                else
                    low=mid+1;
            }
        }
        return -1;
    }

34 Search for a Range(medium)

在一个排序的数组中,找到给点数在数组中一样的数的下标范围

思路:用二分查找,与普通二分查找差异处在于 nums[mid]==target 并没有结束。而是要找到low于mid之间最前面出现的target下标,找到high与mid之间最后面出现的target下标

                 //low
                int tmplow=low,tmphigh=mid-1,tmpmid;
                while(tmplow<=tmphigh)
                {
                    tmpmid=(tmplow+tmphigh)/2;
                    if(nums[tmpmid]==target)
                        tmphigh=tmpmid-1;
                    else
                        tmplow=tmpmid+1;
                }
                result[0]=tmplow;
                //high
                tmplow=mid+1;
                tmphigh=high;
                while(tmplow<=tmphigh)
                {
                    tmpmid=(tmplow+tmphigh)/2;
                    if(nums[tmpmid]==target)
                        tmplow=tmpmid+1;
                    else
                        tmphigh=tmpmid-1;
                }
                result[1]=tmphigh;

35 search insert position

在常规的二分查找的基础上,增加以下的代码即可

 if(nums[mid]>target)
        {
            if(mid==0)
                return 0;
           else
            return mid;
        }
        else
            return mid+1;

36 valid Sudoku

这道题是简单的,只要在3个条件下判断即可(3*3的正方形填充的数字是否要重复的元素,同理去判断每行,每列)只要有重复的元素出现,则返回false

37 sudoku solver (hard)

这道题采用回溯法。每个格子没有存数,则每尝试一个数,先判断是否符合条件(检查每行每列,3*3元素是否存在跟填入的数相等的),符合条件,则进行下一个元素。。。。如果下一个元素返回false,当前元素再尝试一个新值

38 count and say (easy)

这道题在弄懂题目的含义以后,还是很简单的。就是一种新的理解读数方式。讲每个数独立看待,如果有n个一样的数组digit连续出现则用ndigit表示。1—>11 11—>21 111->31

39 combination sum

这道题的思想就是回溯的思想,这种思想在leetcode前面的题目出现过。基本思路进行下一层的遍历。。。返回到当层时,变量要恢复到以前的状态

40 combination sum II

这一题在前一题的基础要多一些考虑。要考虑多个重复的数字的情况下,要如何组合。多个重复的数字为number,重复k次,则要考虑加入1-k次number的结果

41 first missing positive (hard)

这道题的思路就是,通过交换实现,每个数字要对应于一位置。数字i存放在位置i-1,对于不符合条件的数字进行对换。最后,通过一次遍历,不满足条件nums[i]!=i+1,return i+1;

这种解题思路,很多题目中都可以运用的到的

42 trapping rain water (hard)

思路:先找到最大值。然后从两端向中心的最大值遍历。在遍历过程中,每个柱子与遍历的目前最大值比较,如果小于它,面积加上两者之间的差值,如果大于它,则更新目前的最大值

43 multiply (medium)

这道题就是大数相乘

利用我们平时进行乘法的思想运算,从两个数的最低位进行乘法,乘法的结果要加上上次的进位

string multiply(string num1, string num2) {
         if (!num1.compare("0") || !num2.compare("0")) return "0";
                    string num;
            int len1=num1.length();
            int len2=num2.length();
            num.resize(len1+len2);
            int addon=0;
            for(int i=0; i<len1+len2; i++)
            {
                num[i]='0';
            }
            for(int i=len1-1; i>=0; i--)
            {
                addon=0;
                for(int j=len2-1; j>=0; j--)
                {
                    int tmp=num[i+j+1]-'0'+(num1[i]-'0')*(num2[j]-'0')+addon;
                    addon=tmp/10;
                    num[i+j+1]=tmp%10+'0';
                }
                num[i]+=addon;
            }
            if(num[0]=='0')//只可能最高位为0
            {
                num.erase(num.begin());
            }
            return num;
    }

44wildcard matching (hard)

45 jump game II(hard)

比较目前能够到达的最远位置,到达最远位置后,要更新step,即++step,每次遍历更新增加一步能够到达的最远位置

 int jump(vector<int>& nums) {
        int n=nums.size();
        if(n<=1)
            return 0;
        int step = 0;
        int curMax = 0;
        int curRch = 0;
        for(int i = 0; i < n; i ++)
        {
            if(curRch < i)
            {
                step ++;
                curRch = curMax;
            }
            curMax = max(curMax, nums[i]+i);
        }
        return step;
    }

46 permutations (medium)

就是STL中的思路

47 permutations II (medium)

与上题一样

48rotate image(medium)

i=1:n/2
j=1:(n+1)/2
旋转的规律:(i,j)–>(n-1-j,i)
(n-1-j,i)–>(n-1-i,n-1-j)
(n-1-i,n-1-j)–>(j,n-1-i)
(j,n-1-i)–>(i,j)

49 Group anagrams (medium) 看看

用map

map<string, vector<string>> hashMap;
        for(auto &v : strs) {
            string tmp(v);
            sort(tmp.begin(), tmp.end());
            hashMap[tmp].push_back(v);
        }
        vector<vector<string>> result(hashMap.size());
        int k = 0;
        for(auto it = hashMap.begin(); it != hashMap.end(); ++it, ++k) {
            result[k].swap(it->second);
            sort(result[k].begin(), result[k].end());
        }
        return result;

50 pow(x,n) (medium)

用递归思想,result=pow(x,n/2) result=result^2; n为奇数 result=result*x 偶数 result=result

进行运算,需要考虑的特殊情况。x为0,1,-1. n为0. n<0,尤其为INT_MIN。因为负数可以比正数多表示一个数,所有表示为pow(INT_MAX)*x

51 # N-Queens (hard)

用一个大小为N的数组,存储每行Q的位置
最后遍历到row==N时,将结果存入到vector中
判断是否符合条件

bool check(int row, int* place)  
    {  
        for (int i = 0; i < row; ++i)  
        {  
            int diff = abs(place[i] - place[row]);  
            if (diff == 0 || diff == row - i)  
                return false;  
        }  
        return true;  
    }  

52 N-Queens II (hard)

与上一题类似

53 Maximum subarray (medium)

这道题可以用贪心算法的思想,tempsum与maxvalue比较,如果大于则更新maxvalue。如果 tempsum<0,则令tempsum=0. 最后返回maxvalue

54 spiral Matrix (medium)

这道题剑指offer中也有一样的题目。思路就是每次进行循环就是输出了2行2列的矩阵。用一个i表示进行第几次循环,结束条件也就清楚了

一般情况下,一次循环可分割为4次操作。但是要考虑特殊情况。进行一次,两次,三次情况

vector<int> spiralOrder(vector<vector<int>>& matrix) {
        vector<int> result;
        int m=matrix.size();
        if(m==0)
            return result;
        int n=matrix[0].size();
        if(n==0)
            return result;
        int i=0;
        while (m-2*i>0 && n-2*i>0)
        {
            for (int j=i;j<n-i;++j)
            {
                result.push_back(matrix[i][j]);
            }
            for (int j=i+1;j<m-i;++j)
            {
                result.push_back(matrix[j][n-i-1]);
            }
            if (m-i-1>i)
            {
                for (int j=n-i-2;j>=i;--j)
            {
                result.push_back(matrix[m-i-1][j]);
            }
            }
            if (i!=n-i-1)
            {for (int j=m-i-2;j>i;--j)
            {
                result.push_back(matrix[j][i]);
            }
            }
            ++i;
        }
        return result;

    }

55 Jump Game (medium)

这道题采用贪心思想。从头开始遍历。如果maxstep==0,return false maxstep=–maxstep>nums[i] ?maxstep, nums[i];

56 merge intervals (hard)

先对vector根据start大小进行排序,排序结束后,进行合并

57 insert interval (hard)

一共分三种情况,插入的位置在头部,尾部,中间位置
中间位置的情况要找到插入的地方,要确定pre,last坐标

vector<Interval> insert(vector<Interval>& intervals, Interval newInterval) {
       int len=intervals.size();
        vector<Interval> result;
        if(len==0)
        {
            result.push_back(newInterval);
            return result;
        }
        if(newInterval.end<=intervals[0].end)
        {
            if (newInterval.end>=intervals[0].start)
            {
                intervals[0].start=min(intervals[0].start,newInterval.start);
            }
            else
            {       intervals.insert(intervals.begin(),newInterval);
            }
            return intervals;
        }

        if (newInterval.start>=intervals[len-1].start)
        {
        if (newInterval.start<=intervals[len-1].end)
            {
                intervals[len-1].end=max(intervals[len-1].end,newInterval.end);
            }
            else
            {
                intervals.push_back(newInterval);
            }
            return intervals;
        }
        int pre=-1;

        int flag=0;
        for(int i=0;i<len;++i)//确定pre的位置
        {
            if(intervals[i].end<newInterval.start)
            {
                pre=i;
                result.push_back(intervals[i]);
            }
            else
                break;
        }
        int last=pre;
        int i;
        for(i=pre+1;i<len;++i)//确定last位置
        {
            if(intervals[i].start<=newInterval.end)
                last=i;
            else
                break;
        }
        if (pre!=last)
        {   newInterval.start=min(intervals[pre+1].start,newInterval.start);        newInterval.end=max(intervals[last].end,newInterval.end);
        }

        result.push_back(newInterval);
        for(i=last+1;i<len;++i)
            result.push_back(intervals[i]);
        return result;
    }

58 length of last word (easy)

这道题很简单,从后面往前遍历。先找到第一个非空格的位置,再接着找到空格的位置即可

59 spiral matrix II (medium)

这道题与54题类似,可以参照那一题的思路进行

60 permutation sequence (medium)

假设有n个元素,第k个permutation是a1, a2, a3, ….. …, an

那么这里,我们把a1去掉,那么剩下的permutation为
a2, a3, …. …. an, 共计n-1个元素。 n-1个元素共有(n-1)!个排列,那么这里就可以知道

设变量K1 = k
a1 = K1 / (n-1)!// 第一位的选择下标

同理,a2的值可以推导为

K2 = K1 % (n-1)!
a2 = K2 / (n-2)!

。。。。。

K(n-1) = K(n-2) /2!
a(n-1) = K(n-1) / 1!

an = K(n-1)

string getPermutation(int n, int k) {
        int sum=1;
        string str="123456789";
        for(int i=1;i<=n;i++)
            sum=sum*i;
        k--;
        string r="";
        for(int i=n;i>=1;i--)
        {
            sum=sum/i;
            int pos=k/sum;
            r+=str[pos];
            k=k%sum;
            str.erase(pos,1);
        }
        return r;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值