leetcode之贪心算法刷题总结1

leetcode之贪心算法刷题总结1

1-盛最多水的容器
题目链接:题目链接戳这里!!!

思路:这个题最容易想到双重循环的暴力法,O(n^2)的时间复杂度肯定超时,所以我们使用头尾双指针,找出面积最大即可。

AC代码如下:

class Solution {
    public int maxArea(int[] height) {
        int max = 0 ;
        int l = 0 ;
        int r = height.length - 1 ;
        while(l<r){
            int min = Math.min(height[l], height[r]) ;
            int area = min * (r-l) ;
            max = Math.max(max, area) ;
            while(l<r && height[l]<=min){
                l ++ ;
            }
            while(l<r && height[r]<=min){
                r -- ;
            }
        }
        return max ;
    }
}

在这里插入图片描述
2-加油站
题目链接:题目链接戳这里!!!

思路:如果总的汽油量大于总的消耗量,则一定能环绕一周,我们只需要找到一个出发点就可以,从后向前遍历,所剩余的汽油量最多的点就是我们要出发的点。

AC代码如下:

class Solution {
    public int canCompleteCircuit(int[] gas, int[] cost) {
        //只有总的汽油量大于消耗量就一定能绕一周,就是需要确定从那绕,从后往前剩余汽油最多的地方出发
        int left = 0, idx = 0 ; 
        int max = Integer.MIN_VALUE ;
        for(int i=gas.length-1; i>=0; i--){
            left += gas[i]-cost[i] ;
            if(left >= max){
                max = left ;
                idx = i ;
            }
        }
        if(left>=0){
            return idx ;
        }else{
            return -1 ;
        }

    }
}

在这里插入图片描述
3-最大数
题目链接:题目链接戳这里!!!

思路:将所有的整数转换成字符串数组,根据字符串的两两相加进行排序,然后由大到小取出即可。

AC代码如下:

class Solution {
    public String largestNumber(int[] nums) {
        String [] str = new String [nums.length]  ;
        for(int i=0; i<nums.length; i++){
            str[i] = String.valueOf(nums[i]) ;
        }
       Arrays.sort(str, (o1,o2)->(o1+o2).compareTo(o2+o1)) ;
       
        StringBuilder s = new StringBuilder() ;
        for(int i=str.length-1; i>=0; i--){
            s.append(str[i]) ;
        }
        if(s.charAt(0)=='0'){
            return "0" ;
        }
        return new String(s) ;
    }
}

在这里插入图片描述

4-递增的三元子序列
题目链接:题目链接戳这里!!!

思路:每次找出最小的和第二个的,如果出现一个比第二小的大,则是递增三元组。

AC代码如下:

class Solution {
    public boolean increasingTriplet(int[] nums) {
        int a = Integer.MAX_VALUE ;
        int b = Integer.MAX_VALUE ;
        for(int i=0; i<nums.length; i++){
            if(nums[i]<=a){
                a = nums[i] ;
            }else if(nums[i]<=b){
                b = nums[i] ;
            }else{
                return true ;
            }
        }
        return false ;
    }
}

在这里插入图片描述
5-去除重复字母
题目链接:题目链接戳这里!!!

思路:借助栈实现,每次正常进栈,当当前元素比栈顶元素小,并且栈顶元素在后面的字符串中出现,则栈顶元素出栈,当前元素入栈。

AC代码如下:

class Solution {
    public String removeDuplicateLetters(String s) {
        //借助栈实现
        Stack<Character> stack = new Stack<>() ;
        for(int i=0; i<s.length(); i++){
            char c = s.charAt(i) ;
             if(stack.contains(c)){ //栈中已经有该元素,不再处理
                 continue ;
             }
     //当栈不空,且栈顶元素大于当前元素,并且栈顶元素在后面的字符串中回会再出现,则栈顶元素出栈
            while(!stack.isEmpty() && stack.peek()>c && s.indexOf(stack.peek(),i)!=-1){
                stack.pop() ;
            }
            stack.push(c) ;
        }
        String s1 = "" ;
        for(int i=0; i<stack.size(); i++){
            s1 += stack.get(i) ;
        }
        return s1 ;
    }
}

在这里插入图片描述
6-最长回文串
题目链接:题目链接戳这里!!!

思路:将字符的数量分别存储HashMap中,然后偶数个的字符肯定可以凑成回文,奇数个的减去一个变成偶数也能凑成回文数,最后保留有一个最长的奇数也能凑成回文。

AC代码如下:

class Solution {
    public int longestPalindrome(String s) {
       Map<Character,Integer> map = new HashMap<>() ;
       for(int i=0; i<s.length(); i++){
           if(map.get(s.charAt(i)) == null){
               map.put(s.charAt(i), 1) ;
           }else{
              Integer x = map.get(s.charAt(i)) ;
               map.put(s.charAt(i), x+1 );
           }
       }
       int sum = 0, max = 0, r = 0 ;
       boolean flag = false ;
       for(int res : map.values()){
           if((res&1)==0){
               sum += res ;
           }else{
                flag = true ;
                sum += res - 1 ;
               max = Math.max(max, res) ;
           }
       }
       if(flag){
            return sum+max-(max-1) ;
       }
       else{
            return sum ;
       }
    }
}

在这里插入图片描述
7-摆动序列
题目链接:题目链接戳这里!!!

思路:利用摆动序列波峰和波谷的差值最大为1的特点,找出波峰或者波谷的最大值即可。

AC代码如下:

class Solution {
    //利用摆动序列的波峰和波谷差值最大为1的特点
    public int wiggleMaxLength(int[] nums) {
        if(nums.length==1){
            return 1 ;
        }
        int up = 1, down = 1, max = 0 ;
        for(int i=1; i<nums.length; i++){
            if(nums[i-1]>nums[i]){
                up = down + 1 ;
            }
            if(nums[i-1]<nums[i]){
                down =  up + 1 ;
            }
        }
        max = Math.max(up, down) ;
        return max ;
    }
}

在这里插入图片描述
8-整数替换
题目链接:题目链接戳这里!!!

思路:如果是偶数直接除以2,如果二进制是最后两位是11且不是3,则加1,否则减1.

AC代码如下:

class Solution {
    public int integerReplacement(int n) {
        long temp = n ;
        int cnt = 0 ;
        while(temp!=1){
            if((temp&3)==3 && temp!=3){
                temp++;
            }else if((temp&1)==1){
                temp--;
            }else{
                temp >>= 1 ;
            }
            cnt ++ ;
        }
        return cnt ;
    }
}

在这里插入图片描述
递归解法如下:

class Solution {
    public int integerReplacement(int n) {
        return (int)f((long)n);
    }
    public long f(long n){
       if(n==1){
           return 0 ;
       }
       if((n&1)==0){
           return 1+ f(n/2) ;
       }else{
           return 1 + Math.min(f(n+1),f(n-1)) ;
       }
    }
}

在这里插入图片描述
9-移掉k位数字
题目链接:题目链接戳这里!!!

思路:找出第一个右边比左边小的,删除,如果右边的都比左边的大,则删除最后一个。如果前面的有多余的零,清掉。

AC代码如下:

class Solution {
    public String removeKdigits(String num, int k) {
        if(num.length()<=k){
            return "0" ;
        }
        StringBuilder str = new StringBuilder(num) ;

      for(int i=0; i<k; i++){
          int idx = 0;
          for(int j=1; j<str.length() && str.charAt(j)>=str.charAt(j-1); j++){
              idx = j ;
          }
          str.deleteCharAt(idx) ;
      }
       while(str.length() > 1 && str.charAt(0)=='0'){
              str.deleteCharAt(0) ;
          }
      return str.toString() ;
    }
}

在这里插入图片描述
10-最大交换
题目链接:题目链接戳这里!!!

思路:将数字由大到小排序,第一个与原来位置不一样的就是要交换的,要是都有原来一样,则是最大,不需要交换。

AC代码如下:

class Solution {
    public int maximumSwap(int num) {
        String s1 = new String(num+"");
        char [] r = s1.toCharArray() ;
        char [] r1 = new char[r.length] ;
        Arrays.sort(r) ;
          int k=0 ;
            for(int i=r.length-1; i>=0; i--){
                r1[k++] = r[i] ;
            }
        String s2 = String.valueOf(r1) ;
        if(s1.equals(s2)){
            return num ;
        }else{
            char [] a = s1.toCharArray() ;
            char [] b = s1.toCharArray() ; //原来的
            char [] c = new char [a.length] ;//有大到小排序的 
            Arrays.sort(a) ;
            int j=0 ;
            for(int i=a.length-1; i>=0; i--){
                c[j++] = a[i] ;
            }
            char v1='0', v2='0' ;
            int index1 = 0;
            for(int i=0; i<b.length; i++){
                if(b[i] != c[i]){
                   v1 = b[i] ;
                   index1 = i ;
                   v2 = c[i] ;
                    break ;
                }
            }
            int  index2=0;
            for(int i=0; i<b.length; i++){
                if(b[i]==v2){
                    index2 = i ;
                }
            }
            char temp = b[index2] ;
            b[index2] = b[index1] ;
            b[index1] = temp ;
            return Integer.parseInt(String.valueOf(b)) ;
        }
}

}

在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

nuist__NJUPT

给个鼓励吧,谢谢你

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值