leetcode之贪心算法-2021-01-28

题目944.删列造序

  • 循环遍历A,判断每一个字符串是否为倒序

  • 题目有问题,非降序语义不明

  • class Solution {
        public int minDeletionSize(String[] A) {
          /*int ans=0;
            for(int i=0;i<A[0].length();i++){
                for(int j=0;j<A.length-1;j++){
                    if(A[j].charAt(i)<=A[j+1].charAt(i)){
                        ans+=1;
                        break;
                    }
                }
    
               
              
    
            }
            return A[0].length()-ans;*/
            int ans=0;
                for(int i=0;i<A[0].length();i++){
                for(int j=0;j<A.length-1;j++){
                    if(A[j].charAt(i)>A[j+1].charAt(i)){
                        ans+=1;
                        break;
                    }
                }
    
               
              
    
            }
            return ans;
        }
    }
    

题目1005.K次取反后最大化的数组和

  • 选择当前绝对值最大的负数,若负数个数大于等于K,可以每次选择不同的负数直到次数用完。

  • 若都为正数,K若为偶数,则K为0;K为奇数,则K为1,选择一个最小的正数变负。

  • class Solution {
        public int largestSumAfterKNegations(int[] A, int K) {
            Arrays.sort(A);
            int ans=0;
                for(int i=0;i<A.length;i++){
                    if(A[i]<0){
                        A[i]=-A[i];
                        K--;
                    }else if(A[i]==0) {
                        K=0;
                        break;
                    }else {
                       if(K%2>0) {
                           Arrays.sort(A);
                           A[0]=-A[0];
                           K--;
                       }
                        }
                        if(K<=0) break;
                    }
                for(int a:A) ans+=a;
                return ans;
            }
        }
    
    
  • class Solution {
        public int largestSumAfterKNegations(int[] A, int K) {
                //维护最小值索引
                /*Arrays.sort(A);
                int minIndex=0;
                int ans=0;
                while(K>0){
                    A[minIndex]=-A[minIndex];
                    K--;
                    if(minIndex+1<A.length&&A[minIndex]>A[minIndex+1]) minIndex+=1;
                }
                for(int a:A) ans+=a;
                return ans;*/
                
        }
    }
    

    这个代码是更加接近问题本质的代码。

题目1046.最后一块石头的重量

  • 对数组排序,取后两个比较大小,相等则减去本身,不等则减去小的,再次排序,循环,判断

  • class Solution {
        public int lastStoneWeight(int[] stones) {
            Arrays.sort(stones);
            int len=stones.length;
            while(len>=2&&stones[len-2]!=0){
                if(stones[len-2]==stones[len-1]) {
                    stones[len-2]=0;
                    stones[len-1]=0;
                }else {
                    stones[len-1]-=stones[len-2];
                    stones[len-2]=0;
                }
                Arrays.sort(stones);
    
            }
            
            return stones[len-1];
        }
    }
    

题目1217.玩筹码

  • 贪心策略:能用第二种方式绝不用第一种,这样可以将所有偶数位置移动到同一位置(任意偶数位置),不妨设为P[2],同理所有奇数位置移动到P[1],这样只需将偶数或奇数位置 硬币数少的那堆移动1位即可,而硬币数正好为奇数位置硬币数目之和或偶数位置硬币数目之和。

  • class Solution {
        public int minCostToMoveChips(int[] position) {
            int odd=0,even=0;
            for(int a:position){
                if(a%2==0) even++;
                else odd++;
            }
            return Math.min(even,odd);
        }
    }
    

题目1221.分割平衡字符串

  • class Solution {
        public int balancedStringSplit(String s) {
            Deque<Character> stack=new LinkedList<>();
            int ans=0;
            
    
            stack.push(s.charAt(0));
            for(int i=1;i<s.length();i++){
                    if(stack.peek()==s.charAt(i)) stack.push(s.charAt(i));
                    else stack.pop();
                    if(stack.isEmpty()) {
                        ans++;
                        i++;
                        if(i<s.length()) stack.push(s.charAt(i));
                        else break;
    
                    }
            }
            
           return ans; 
        }
    }
    

题目1403.非递增顺序的最小子序列

  • class Solution {
        public List<Integer> minSubsequence(int[] nums) {
            List<Integer> list=new ArrayList<>();
            //贪心算法:找当前数组中最大的元素,判断是否大于剩下元素和
            Arrays.sort(nums);
            int MAX=0;
            list.add(nums[nums.length-1]);
            Iterator it=list.iterator();
            for(int i=nums.length-1;i>=0;i--){
                int ans=0;
                int sum=0;
                for(int j=0;j<i;j++) {
                    ans+=nums[j];
                }
                    for(int j=0;j<list.size();j++){
                        sum+=list.get(j);
                    }
                if(sum<=ans) list.add(nums[i-1]);
                else break;
            }
            return list;
        }
    }
    
    class Solution {
        public List<Integer> minSubsequence(int[] nums) {
           List<Integer> list=new ArrayList<>();
            //贪心算法:找当前数组中最大的元素,判断是否大于剩下元素和
            Arrays.sort(nums);
            int sum=0;
            int ans=0;
            Iterator it=list.iterator();
            for(int n:nums) {
                sum+=n;
            }
            for(int i=nums.length-1;i>=0;i--){
                list.add(nums[i]);
                sum-=nums[i];
                ans+=nums[i];
                if(ans>sum) break;
            }
            return list;
    
        }
    }
    
  • 同样的思路,修改一下,去掉遍历ArrayList能快不少,内存占用也少不少,

题目1518.换酒问题

  • 一开始能和numBottles瓶,然后每轮就只能喝换到的酒,换到的酒的酒瓶加上上一轮剩下的酒瓶是这次拿去换酒的酒瓶,赋给bottle,循环到换不起酒为止。

  • class Solution {
        public int numWaterBottles(int numBottles, int numExchange) {
            int ans=numBottles;
            while(numBottles/numExchange>0){
                ans+=numBottles/numExchange;
                numBottles=numBottles/numExchange+numBottles%numExchange;  
            }
            return ans;
        }
    }
    

题目1710.卡车上的最大单元数

  • 优先选目前能装最多单元的箱子,直到truckSize或用完。

  • 建立一个哈希表存储箱子对应单元数,对二维数组按第二元素排序,倒序访问算出装单元数之和,计算所用享资总和与truckSize比较,等于时退出。

  • class Solution {
        public int maximumUnits(int[][] boxTypes, int truckSize) {
            //贪心策略
                          //贪心策略
    
                int ans=0,sum=0;
                Arrays.sort(boxTypes, new Comparator<int[]>() {
                    @Override
                    public int compare(int[] a, int[] b) {
                        return b[1]-a[1];
                    }
                });
                int len=boxTypes.length;
                for(int j=0;j<len;j++) {
                    ans+=boxTypes[j][0];
                    if(ans<truckSize) sum+=boxTypes[j][1]*boxTypes[j][0];
                    else {
                        sum+=boxTypes[j][1]*(truckSize-ans+boxTypes[j][0]);
                        break;
                    }
                }
                return sum;
    
        }
    }
    
  • 本题知识点,Arrays.sort()排序

  • Arrays.sort(boxTypes, new Comparator<int[]>() {
        @Override
        public int compare(int[] a, int[] b) {
            return b[1]-a[1];
            //sort()方法默认从小到大排序,comparator()方法,a是前一个元素,b是后一个元素,返回正值说明a>b,返回负值说明a<b,返回0说明a=b。不难理解这个语法,加入comparator()sort会根据其返回值确定a和b的大小进而从小到大排序,如果重写compare()方法时 a>b返回正值,sort就会将b排到a的前面,实现从小到大。如果我们想逆序排列,只需骗过sort,a>b时返回负值,a<b时返回正值,sort认为a>b,就会把b排在a的前面,从而实现降序排列
        }
    });
    

题目1716.计算力扣银行的钱

  • class Solution {
        public int totalMoney(int n) {
            double b=0;
            if(n>7){
            b=(n/7+1)*(n%7)+(n%7)*(n%7-1)*0.5+28*(n/7)+3.5*(n/7)*(n/7-1);
            }else{
                b=(n*n+n)/2;
            }
            return (int)b;
        }
    }
    //速度快,但内存占用较大
    
  • class Solution {
        public int totalMoney(int n) {
            int sum=0;
            int i=1,j=7;
            if(n<8) return sum=(n+1)*n/2;
           while(n>=7){
                n-=7;
                sum+=(i+j)*(j-i+1);
                i++;
                j++;
            }
            sum/=2;
            while(n>0){
                sum+=i;
                n--;
                i++;
            }
    
            return sum;
        }
    }
    //内存占用也不少
    

题目1725.可以形成最大正方形的矩形数目

  • class Solution {
        public int countGoodRectangles(int[][] rectangles) {
            int[] arr=new int[rectangles.length];
            for(int i=0;i<rectangles.length;i++){
                if(rectangles[i][0]<=rectangles[i][1]) arr[i]=rectangles[i][0];
                else arr[i]=rectangles[i][1];
            }
            Arrays.sort(arr);
            int ans=0;
            for(int i=0;i<arr.length;i++){
                if(arr[i]==arr[arr.length-1]) ans++;
            }
            return ans;
        }
    }
    
  • class Solution {
        public int countGoodRectangles(int[][] rectangles) {        
    // 当前遍历过的所有正方形中最长的边长
            int maxLength = 0;
            // 正在遍历的正方形的边长
            int tempLength;
            // 当前遍历过的边长等于最长边长的正方形个数
            int count = 1;
            for (int i = 0; i < rectangles.length; i++) {
                // 当前正方形的边长
                tempLength = Math.min(rectangles[i][0], rectangles[i][1]);
                // 当前的正方形的边长是最大的,所以count变成1且最大值发生改变
                if (tempLength > maxLength) {
                    maxLength = tempLength;
                    count = 1;
                // 当前边长最大的正方形个数加一
                } else if (tempLength == maxLength) {
                    count++;
                }
            }
            return count;
        }
    }
    
    
    
    
    

题目1736.替换隐藏数字得到的最晚时间

  • class Solution {
        public String maximumTime(String time) {
            StringBuffer str=new StringBuffer();
          char ze=time.charAt(0);
          char on=time.charAt(1);
          char th=time.charAt(3);
          char fo=time.charAt(4);
          char ONE='1';
          char FOUR='4';
          char NINE='9';
          char THREE='3';
          char FIVE='5';
          char ZERO='0';
                if(ze=='?'){
                    if(on<FOUR||on=='?') {
                        ze='2';
                        str.append(ze);
                    }else {
                        ze='1';
                        str.append(ze);
                    }
                }else str.append(ze);
                if(on=='?'){
                    if(ze==ONE) {
                        on=NINE;
                        str.append(on);
                    }if(ze==ZERO) {
                        on=NINE;
                        str.append(on);
                    }if(ze=='2'){
                        on=THREE;
                        str.append(on);                    
                    }
                }  else str.append(on);
                str.append(':');
                if(th=='?'){
                    th=FIVE;
                    str.append(th);
                }else str.append(th);       
                if(fo=='?'){
                    fo=NINE;
                    str.append(fo);
                }else str.append(fo);   
    
                
            
            return str.toString();
        }
    }
    
  • 
    class Solution {
        public String maximumTime(String time) {
            StringBuffer str=new StringBuffer();
          char ze=time.charAt(0);
          char on=time.charAt(1);
          char th=time.charAt(3);
          char fo=time.charAt(4);
                if(ze=='?'){
                    if(on<'4'||on=='?') {
                        ze='2';
                        str.append(ze);
                    }else {
                        ze='1';
                        str.append(ze);
                    }
                }else str.append(ze);
                if(on=='?'){
                    if(ze=='1') {
                        on='9';
                        str.append(on);
                    }if(ze=='0') {
                        on='9';
                        str.append(on);
                    }if(ze=='2'){
                        on='3';
                        str.append(on);                    
                    }
                }  else str.append(on);
                str.append(':');
                if(th=='?'){
                    th='5';
                    str.append(th);
                }else str.append(th);       
                if(fo=='?'){
                    fo='9';
                    str.append(fo);
                }else str.append(fo);   
            return str.toString();
            
            
            /*if(one=='?'){
                if(two=='?'){
                    str.append('2').append('3');
                }else{
                    if(two<'4'){
                        str.append('2').append(two);
                    }else{
                        str.append('1').append(two);
                    }
                }
            }else if(one=='2'){
                if(two=='?'){
                    str.append('2').append('3');
                }else str.append('2').append(two);
            }else {
                if(two=='?'){
                    str.append(one).append('9');
                }else str.append(one).append(two);            
            }
            str.append(':');
            if(three=='?'){
                str.append('5');
    
            }else str.append(three);
            if(four=='?'){
                str.append('9');
            }else str.append(four);
            return str.toString();*/
        }
    }
    
    
  • 同样是if else为什么性能会有差距呢?

接下来一周到两周就不是天天全部时间刷题了,学一学数据结构。上午和下午学数据结构,晚上刷题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值