leetcode刷题指南

来源:互联网 发布:整形网络咨询怎么样 编辑:程序博客网 时间:2024/05/16 08:20

26. Remove Duplicates from Sorted Array

题目要求返回得到的数组长度,但是不允许生成新的空间,只能在原数组上进行操作,所以返回长度就相当于返回处理之后的数组。

因为是排序后的数组,所以相同的数字都相邻,用相邻的两个指针来表示即可,若前后不相等,nums[j++]=nums[i],即对应位置的数组等于前一个。若前后相等,j不变,相当于去掉相同的,把后面的数组移动一个位置。最后,补上数组最后一个值即可。并返回数组长度。


55. Jump Game(hard for me)

用reach表示下标为i的数组能到达的最远的下标位置,循环判断条件中i<=reach表示i能到达,遍历0到n-1,看看这些位置的数组是否都能到达,如果i>reach退出循环时 i!=n,不能到达结尾,否则,遍历到最后一个退出循环时i=n,能到达末尾。


33. Search in Rotated Sorted Array

left和mid和right指的是该位置所在的数组值。

利用二分法实现,题目说明,旋转后,最大的一定不在最右侧,如果mid<right,则说明为6712345类似的,对于①mid<target<=right型,则target在靠右侧,left=mid+1;②否则,target在靠左侧,right=mid-1;③如果mid>=right,则为3456712类似的,对于left<=target<mid型,则target在靠左侧,right=mid-1;④否则,target在靠右侧,left=mid+1;

更新mid,直至left>right退出循环。

边界值:target==mid  返回mid

            target==right     应该left移动,

            target==left       应该right移动  


34. Search for a Range

题目要求时间复杂度是o(logn),注意二分搜索的时间复杂度为o(logn),采用二分搜索。

和33题的思路一致,主要的是获得第一个和最后一个相同元素的位置。

找最大的位置(找最小位置同理)

while(left<=right){
            mid=(left+right)/2;
            if(nums[mid]<=target){     //相等和小于,都向右半区移动
                left=mid+1;
            }
           if(nums[mid]>target){
               right=mid-1;
           }
           if(nums[mid]==target)  //记录下当前时刻,等于target的id值,left>right退出循环时,即为最右侧的id值
               id=mid;
        }


53. Maximum Subarray

DP      动态规划的关键在于求得公式,描述当前位置和之前位置的关系。

已经得到i-1处的的最大值,计算第i处的最大值。找到两个状态之间的关系

 for(int i=1;i<nums.length;i++){
            maxnow=Math.max(nums[i],maxnow+nums[i]);  //********
            maxsofar=Math.max(maxsofar,maxnow);
        }
        return maxsofar;

******处至关重要,不能比较maxnow和maxnow+nums[i],因为是连续的数的和

maxnow表示,第i-1处的最大值,那么第i处的最大值就是nums[i]或者maxnow+nums[i](必须要算第i处的值)。然后用maxsofar,记录截止到i处,之前的最大值。


70. Climbing Stairs-------DP

       dp[1]=1;   //上一级台阶有一种可能
       dp[2]=2;  //上两级台阶有1+1或2两种可能
       for (int i=3;i<=n;i++){
           dp[i]=dp[i-1]+dp[i-2];  //以4级台阶为例,要么从第2级走2步,要么从第3级走1                                                       步,有dp[2]+dp[3]种可能。
       }


66. Plus One

 int add=1;
        for(int i=digits.length-1;i>=0;i--){
            if(digits[i]+add==10){    //不能写为digits[i]==9因为等于9如果后面没有进位,还                                                      是不变的
                digits[i]=0;
                add=1;
            }
            else{
            digits[i]=digits[i]+add;
            add=0;
            }
        }
        if(add==1){
           int res[]=new int[digits.length+1];
           System.arraycopy(digits,0,res,1,digits.length);  //如果99变成100,需要加1进                                                                                            位,多一个空间,利用arraycopy                                                                                      函数将数组复制过来
           res[0]=1;
           return res;
        }
        else
            return digits;
    }


198. House Robber

由于连续两个数不能相加,分为奇数位置和偶数位置两种情况,为奇数位置时,要么是上一个奇数处的和值加上这个奇数处的值,要么是上一个偶数处的和值。偶数位置同理。用a,b分别表示两种情况的和,然后返回一个最大值。


62. Unique Paths

第i,j处,要么从i-1,j处过来,要么从i,j-1处过来,即num[i][j]=num[i-1][j]+num[i][j-1]

注意初始值,第0行,第0列的值均为1,。


279. Perfect Squares

s[0]=0

s[1]=1

s[2]=2

s[3]=3

s[4]=min(s[4-1]+1,s[4-4]+1)=1

s[17]=min(s[17-1]+1,s[17-4]+1,s[17-9]+1,s[17-16]+1)

想求得和为n的完全平方数的个数,即和为n-1,n-4,n-9.....处的值+1个的最小值;


134. Gas Station

假设从0开始,如果sum=sum+gas-cost>0  end表示能到达的地方为B  end++;

如果sum<0 表示不能从0到达B  则0至B之间的任何一个点都无法到达B(因为0能到达B之前的一个点,说明0到该点的sum大于0,减去之后更到达不了) 则开始的点要向前移动  start=gas.length,start-- ,如果sum<0 则无法绕一圈 ,返回-1   如果sum>0 &&start==gas.length  则从0开始,返回0。如果sum>0 &&start!=gas.length,则从start开始,返回start 


206. Reverse Linked List

!!!!!!!!!!!利用指针的想法来思考问题

newhead=head;       newhead指针指向head

迭代方法:




递归方法:

思想一致,每次删掉旧链表的头结点,接为已翻转新链表的头。用newHead表示新链表的头,head为旧链表的头,head.next=newHead。用nextNode表示头的下一个节点,暂存起来。

237. Delete Node in a Linked List

      删除的节点无法找到前一个节点,所以不能用传统的方法,把前一个节点接到后一个节点上,所以将本节点复制成和下一个节点一样,然后删除下一个即可。

a->b->c->d

如果要删除b

则  改为 a->c->c->d

删除第二个c

a->c->d    大功告成


234. Palindrome Linked List

In the beginning, set two pointers fast and slow starting at the head.

1 -> 1 -> 2 -> 1 -> null 

sf

(1) Move: fast pointer goes to the end, and slow goes to the middle.

1 -> 1 -> 2 -> 1    偶数     s         f    
1 -> 1 -> 2 -> 1 ->1    奇数          s        f    
令 left=head     right=slow   左边稍微短一点(奇数的话)

(2) Reverse: the right half is reversed, and newhead pointer becomes the 2nd head.

1 -> 1              2 <- 1           left                    newhead

(3) Compare: run the two pointer left and newhead together and compare.

1 -> 1             2 <- 1                 left          newhead
因为左边短一点,所以在比较的时候以left!=null作为循环条件来进行
注意:算法在设计时一定要考虑到[],[1],[1,1],[1,2,1]等出现空指针的情况。