leetcode周期小结2

以下更好的解法均来自网络

6.Z字形变换

将字符串 "PAYPALISHIRING" 以Z字形排列成给定的行数:

P   A   H   N
A P L S I I G
Y   I   R

之后从左往右,逐行读取字符:"PAHNAPLSIIGYIR"

实现一个将字符串进行指定行数变换的函数:

string convert(string text, int nRows);

convert("PAYPALISHIRING", 3) 应当返回 "PAHNAPLSIIGYIR" 。

个人解法:先用算出同一列中两个元素的关系,然后循环,循环。。。

class Solution {
     public static String convert(String s, int numRows) {
        int distance= 2*numRows-2;
        int eachpart=distance-1;
        if(numRows==1) return s;
        else
        return function(s,0,0,numRows,0);
    }

    public static String function(String s,int nowrow,int distance,int numRows,int nownum)  {
        if(nowrow==numRows)      return "";
        if(nownum>=s.length())   return  function(s,nowrow+1,2*numRows-2-2*(nowrow+1),numRows,nowrow+1);
        if(nowrow==0)            return  s.charAt(nownum)+function(s,nowrow,2*numRows-2,numRows,nownum+2*numRows-2)  ;
        if(nowrow==numRows-1)    return  s.charAt(nownum)+function(s,nowrow,2*numRows-2,numRows,nownum+2*numRows-2)  ;
        return     s.charAt(nownum)+function(s,nowrow,2*numRows-2-distance,numRows,nownum+distance)  ;
    }

}


更好的解法:

输入:一个字符串和行数

首先将string转换为字符数组使用toCharArray()
所以每一行用一个StringBuilder对象来保存,因为可以更改其值。
主要确定好两个方向的位置,竖向和倾斜。只需要控制好sb的下标即可。

注意:
在控制sb下标的同时也一定要控制字符数组的下标,防止越界。

public class Solution {
    public String convert(String s, int numRows) {

        char[] c=s.toCharArray();

        StringBuilder[] sb=new StringBuilder[numRows];

        for(int i=0;i<numRows;i++)
        {
            sb[i]=new StringBuilder();
        }

        int k=0;
        while(k<s.length())
        {
            for(int i=0;i<numRows && k<s.length();i++)
            {
                sb[i].append(c[k++]);
            }

            for(int i=numRows-2;i>=1 && k<s.length();i--)
            {
                sb[i].append(c[k++]);
            }


        }


        StringBuilder result=new StringBuilder();
        for(int i=0;i<numRows;i++)
        {
            result.append(sb[i]);
        }

        return result.toString(); 




    }
}

14.最长公共前缀

编写一个函数来查找字符串数组中的最长公共前缀。

个人解法:以第一个字符串的全部为基准,每扫描一个逐渐减少

class Solution(object):
    def longestCommonPrefix(self, strs):
        if strs == []:
            return ""
        if len(strs)==1:
            return strs[0]
        left = 0
        right = len(strs[0])
        for i in range(0, len(strs)):

            if right >len(strs[i]):
                right = len(strs[i])
            a = self.check(strs, i, left, right)
            right=a
        result=""
        for i in range(0,right):
            result=result+strs[0][i]
        return result

    def check(self, strs, pos, left, right):
        
        for i in range(left, right):
            if strs[pos][i] == strs[0][i]:
                pass
            else:
                return i

        return right

更好的解法:有待寻找


45.跳跃游戏2

给定一个非负整数数组,你最初位于数组的第一个位置。

数组中的每个元素代表你在该位置可以跳跃的最大长度。

你的目标是使用最少的跳跃次数到达数组的最后一个位置。

例如: 
给定数组 A = [2,3,1,1,4]

跳到最后一个位置的最小跳跃数是 2。(从下标为 0 跳到下标为 1 的位置,跳 1 步,然后跳 3 步到达数组的最后一个位置。)

注意:

假设你总是可以到达数组的最后一个位置。

个人解法:贪心算法,并记录下上次检索的最右端来减少下次所需检索的元素数量

写的时候可以变成:每次检索元素的时候都与前面能跳最远的比较(n),然后只考虑什么时候counter需要+1就好了

class Solution:
    def jump(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        if len(nums)==1:
            return 0
        pos=0
        temppos=0
        counter=0
        for i in range(0,len(nums)):
            if nums[i]+i>=len(nums)-1:
                if i<=nums[pos]+pos and i>pos:
                    return counter+2
                else:
                    return counter+1

            temppos=self.max(temppos,i,nums)


            if i==nums[pos]+pos:
                counter=counter+1
                pos=temppos



    def max(self, a, b,nums):
        if nums[a]+a>nums[b]+b:
            return a
        else:

            return b

更好的解法:待定


495.提莫攻击

在《英雄联盟》的世界中,有一个叫“提莫”的英雄,他的攻击可以让敌方英雄艾希(编者注:寒冰射手)进入中毒状态。现在,给出提莫对艾希的攻击时间序列和提莫攻击的中毒持续时间,你需要输出艾希的中毒状态总时长。

你可以认为提莫在给定的时间点进行攻击,并立即使艾希处于中毒状态。

示例1:

输入: [1,4], 2
输出: 4
原因: 在第1秒开始时,提莫开始对艾希进行攻击并使其立即中毒。中毒状态会维持2秒钟,直到第2秒钟结束。
在第4秒开始时,提莫再次攻击艾希,使得艾希获得另外2秒的中毒时间。
所以最终输出4秒。

示例2:

输入: [1,2], 2
输出: 3
原因: 在第1秒开始时,提莫开始对艾希进行攻击并使其立即中毒。中毒状态会维持2秒钟,直到第2秒钟结束。
但是在第2秒开始时,提莫再次攻击了已经处于中毒状态的艾希。
由于中毒状态不可叠加,提莫在第2秒开始时的这次攻击会在第3秒钟结束。
所以最终输出3。


个人解法:递归,遍历,尽量用if来减少赋值的时间

class Solution {
   public static int findPoisonedDuration(int[] timeSeries, int duration) {
       if(timeSeries.length==0)
           return 0;
       else
           return run(timeSeries,duration,0);
    }
    static int p;
    public static int run(int[] timeSeries,int duration,int now)
    {

        if(now>=timeSeries.length-1)
         { return duration;}
         else
        {  p=timeSeries[now+1]-timeSeries[now];}

        return (p>=duration?duration:p)+run(timeSeries,duration,now+1);
    }
    

}

更好的解法:待寻

605.种花问题

假设你有一个很长的花坛,一部分地块种植了花,另一部分却没有。可是,花卉不能种植在相邻的地块上,它们会争夺水源,两者都会死去。

给定一个花坛(表示为一个数组包含0和1,其中0表示没种植花,1表示种植了花),和一个数 。能否在不打破种植规则的情况下种入 朵花?能则返回True,不能则返回False。

示例 1:

输入: flowerbed = [1,0,0,0,1], n = 1
输出: True

示例 2:

输入: flowerbed = [1,0,0,0,1], n = 2
输出: False

注意:

  1. 数组内已种好的花不会违反种植规则。
  2. 输入的数组长度范围为 [1, 20000]。
  3. n 是非负整数,且不会超过输入数组的大小。

个人解法:暴力遍历,检测是否符合情况,赋值

class Solution {
       public static boolean canPlaceFlowers(int[] flowerbed, int n) {
        if(n==0) return true;
        if(flowerbed.length==1){if(flowerbed[0]==0&&n<=1) return true;else return false;}
       for(int i=0;i<flowerbed.length;i++)
       {
           if(check(flowerbed,i)==true) {n--;flowerbed[i]=1;}
           if(n==0) return true;
       }
       return false;

    }


    public static boolean check(int[] flowerbed, int pos){
            if (pos == 0)
            if (flowerbed[pos] == 0 && flowerbed[pos + 1] == 0)
            return true;
            else
                    return false;
        if (pos == flowerbed.length - 1)
            if (flowerbed[pos] == 0 & flowerbed[pos - 1] == 0)
            return true;
            else
                    return false;
        if(flowerbed[pos] == 0 && flowerbed[pos + 1] == 0 && flowerbed[pos - 1] == 0)
            return true;
        else
                return false;

}

}

更好的解法:计算两个1之间有几个数,即可确定最大能放多少

bool canPlaceFlowers(int* flowerbed, int flowerbedSize, int n) {
    
    int l = -2;
    int r;
    int sum = 0;
    for (r = 0; r < flowerbedSize; ++r){
        if (flowerbed[r] == 1){
            sum = sum + floor((r-l-2) / 2.0);
            l = r;
        }
    }
    sum = sum + floor((flowerbedSize-l-1) / 2.0);
    
    return sum>=n?true:false;
}








阅读更多

没有更多推荐了,返回首页