Leecode刷题

1109. 航班预订统计

难度 中等

这里有 n 个航班,它们分别从 1 到 n 进行编号。

有一份航班预订表 bookings ,表中第 i 条预订记录 bookings[i] = [firsti, lasti, seatsi] 意味着在从 firsti 到 lasti (包含 firsti 和 lasti )的 每个航班 上预订了 seatsi 个座位。

请你返回一个长度为 n 的数组 answer,其中 answer[i] 是航班 i 上预订的座位总数。

示例 1:

输入:bookings = [[1,2,10],[2,3,20],[2,5,25]], n = 5
输出:[10,55,45,25,25]
解释:
航班编号        1   2   3   4   5
预订记录 1 :   10  10
预订记录 2 :       20  20
预订记录 3 :       25  25  25  25
总座位数:      10  55  45  25  25
因此,answer = [10,55,45,25,25]

示例 2:

输入:bookings = [[1,2,10],[2,2,15]], n = 2
输出:[10,25]
解释:
航班编号        1   2
预订记录 1 :   10  10
预订记录 2 :       15
总座位数:      10  25
因此,answer = [10,25]

暴力题解

class Solution {
    public int[] corpFlightBookings(int[][] bookings, int n) {
         int []res=new int[n];
       for (int i = 0; i <bookings.length ; i++) {
           for(int j=bookings[i][0];j<=bookings[i][1];j++){
                  res[j-1]=res[j-1]+bookings[i][2];
           }
        }
        return res;

    }
}

 2官方题解:差分法

可以看看大佬对差分法的解释:

换一种思路理解题意,将问题转换为:某公交车共有 n 站,第 i 条记录 bookings[i] = [i, j, k] 表示在 i 站上车 k 人,乘坐到 j 站,在 j+1 站下车,需要按照车站顺序返回每一站车上的人数
根据 1 的思路,定义 counter[] 数组记录每站的人数变化,counter[i] 表示第 i+1 站。遍历 bookings[]:bookings[i] = [i, j, k] 表示在 i 站增加 k 人即 counters[i-1] += k,在 j+1 站减少 k 人即 counters[j] -= k
遍历(整理)counter[] 数组,得到每站总人数: 每站的人数为前一站人数加上当前人数变化 counters[i] += counters[i - 1]

public class CorporateFlightBookings {
    public int[] corpFlightBookings(int[][] bookings, int n) {
        int[] counters = new int[n];
        for (int[] booking : bookings) {
            counters[booking[0] - 1] += booking[2];
            if (booking[1] < n) {
//根据题意如果不是完全做到头的话,比如做到第k站,就会在k+1站下车。每次循环先把数组索引为下车站出的 
// 值减去booking[2]
                counters[booking[1]] -= booking[2];
            }
        }
//前缀和,这一站的人为没下车的人+本站上车的人
        for (int i = 1; i < n; ++i) {
            counters[i] += counters[i - 1];
        }
        return counters;
    }
}


520. 检测大写字母

难度简单137收藏分享切换为英文接收动态反馈

给定一个单词,你需要判断单词的大写使用是否正确。

我们定义,在以下情况时,单词的大写用法是正确的:

  1. 全部字母都是大写,比如"USA"。
  2. 单词中所有字母都不是大写,比如"leetcode"。
  3. 如果单词不只含有一个字母,只有首字母大写, 比如 "Google"。

否则,我们定义这个单词没有正确使用大写字母。

示例 1:

输入: "USA"
输出: True

示例 2:

输入: "FlaG"
输出: False

两种笨方法 

class Solution {
    public boolean detectCapitalUse(String word) {
        int len=word.length();
        int big=0,small=0;
        for(int i=0;i<len;i++){
            if(word.charAt(i)-'a'>=0){
                small++;
            }else{
                big++;
            }
        }
        return big==len||big==0||word.charAt(0)-'a'<0 && big==1;
       
    }
}

class Solution {
    public boolean detectCapitalUse(String word) {
        int len=word.length();
        int big=0,small=0;
        for(int i=0;i<len;i++){
            if(((int)word.charAt(i))>=65 && ((int)word.charAt(i))<=90){
                big++;
            }
        }
        return big==len||big==0||((int)word.charAt(0))>=65 && ((int)word.charAt(0))<=90 &&big==1;
       
    }
}

 


 451. 根据字符出现频率排序

难度中等329收藏分享切换为英文接收动态反馈

给定一个字符串,请将字符串里的字符按照出现的频率降序排列。

示例 1:

输入:
"tree"

输出:
"eert"

解释:
'e'出现两次,'r'和't'都只出现一次。
因此'e'必须出现在'r'和't'之前。此外,"eetr"也是一个有效的答案。

示例 2:

输入:
"cccaaa"

输出:
"cccaaa"

解释:
'c'和'a'都出现三次。此外,"aaaccc"也是有效的答案。
注意"cacaca"是不正确的,因为相同的字母必须放在一起。

示例 3:

输入:
"Aabb"

输出:
"bbAa"

解释:
此外,"bbaA"也是一个有效的答案,但"Aabb"是不正确的。
注意'A'和'a'被认为是两种不同的字符。

学会使用StringBuffer和StringBuilder解决问题,因为String使用不方便,一旦定义好就是固定的,不会被改变,给字符串重新赋值并不是改变,而是变量指向改变了。 


class Solution {
    public String frequencySort(String s) {
        HashMap<Character,Integer>  map=new HashMap<>();
//统计出现的频率
        for(int i=0;i<s.length();i++){
            char c=s.charAt(i);
            int x=map.getOrDefault(c,0)+1;
            map.put(c,x);
        }
        StringBuilder res=new StringBuilder();
        Map<Character,Integer> tmp=new HashMap(map);
        for(int i=0;i<s.length();i++){
            for(char c:tmp.keySet()){
//对频率-1,为0的话,就插入原频率个该字符
                tmp.put(c,tmp.get(c)-1);
                if(tmp.get(c)==0){
                    for(int j=0;j<map.get(c);j++){
                        res.append(c);
                    }
                }
            }
        }
//对结果进行反转,得到正确结果。
 return   res.reverse().toString();
    }
}

 

1588. 所有奇数长度子数组的和

难度简单126收藏分享切换为英文接收动态反馈

给你一个正整数数组 arr ,请你计算所有可能的奇数长度子数组的和。

子数组 定义为原数组中的一个连续子序列。

请你返回 arr 中 所有奇数长度子数组的和 。

示例 1:

输入:arr = [1,4,2,5,3]
输出:58
解释:所有奇数长度子数组和它们的和为:
[1] = 1
[4] = 4
[2] = 2
[5] = 5
[3] = 3
[1,4,2] = 7
[4,2,5] = 11
[2,5,3] = 10
[1,4,2,5,3] = 15
我们将所有值求和得到 1 + 4 + 2 + 5 + 3 + 7 + 11 + 10 + 15 = 58
示例 2:输入:arr = [1,2]
输出:3
解释:总共只有 2 个长度为奇数的子数组,[1] 和 [2]。它们的和为 3 。
示例 3:输入:arr = [10,11,12]
输出:66
class Solution {
    public int sumOddLengthSubarrays(int[] arr) {
        int len=arr.length;
        int sum=0;
        for(int i=1;i<=len;i+=2){
            for(int k=0;k<len-i+1;k++){
                for(int x=0;x<i;x++){
                    sum+=arr[x+k];
                }
            }
        }
return  sum;
    }
}

 


剑指 Offer 50. 第一个只出现一次的字符

难度简单129收藏分享切换为英文接收动态反馈

在字符串 s 中找出第一个只出现一次的字符。如果没有,返回一个单空格。 s 只包含小写字母。

示例:

s = "abaccdeff"
返回 "b"
s = "" 
返回 " "

class Solution {
    public char firstUniqChar(String s) {
        for(int i=0;i<s.length();i++){
            char c=s.charAt(i);
           if(s.indexOf(c)==i && s.indexOf(c,i+1)==-1){
               return c;
           }
           
        }
       return ' ';
    }
}

 


剑指 Offer II 012. 左右两边子数组的和相等

难度简单4收藏分享切换为英文接收动态反馈

给你一个整数数组 nums ,请计算数组的 中心下标 

数组 中心下标 是数组的一个下标,其左侧所有元素相加的和等于右侧所有元素相加的和。

如果中心下标位于数组最左端,那么左侧数之和视为 0 ,因为在下标的左侧不存在元素。这一点对于中心下标位于数组最右端同样适用。

如果数组有多个中心下标,应该返回 最靠近左边 的那一个。如果数组不存在中心下标,返回 -1 。

示例 1:

输入:nums = [1,7,3,6,5,6]
输出:3
解释:
中心下标是 3 。
左侧数之和 sum = nums[0] + nums[1] + nums[2] = 1 + 7 + 3 = 11 ,
右侧数之和 sum = nums[4] + nums[5] = 5 + 6 = 11 ,二者相等。

示例 2:

输入:nums = [1, 2, 3]
输出:-1
解释:
数组中不存在满足此条件的中心下标。

示例 3:

输入:nums = [2, 1, -1]
输出:0
解释:
中心下标是 0 。
左侧数之和 sum = 0 ,(下标 0 左侧不存在元素),
右侧数之和 sum = nums[1] + nums[2] = 1 + -1 = 0 。

思路:如果i是结果,i前数组元素和x,则x*2+nums[i]=sum

class Solution {
    public int pivotIndex(int[] nums) {
        int  sum=0;
        for(int i=0;i<nums.length;i++){
             sum+=nums[i];
        }
       
        int x=0;
        for(int i=0;i<nums.length;i++){
           if(i==0){
               x=0;
           }else{
               x+=nums[i-1];
           }
            if(x*2+nums[i]==sum){
                return  i;
            }
        }
   return  -1;
    }
}

 


剑指 Offer 62. 圆圈中最后剩下的数字

难度简单430收藏分享切换为英文接收动态反馈

0,1,···,n-1这n个数字排成一个圆圈,从数字0开始,每次从这个圆圈里删除第m个数字(删除后从下一个数字开始计数)。求出这个圆圈里剩下的最后一个数字。

例如,0、1、2、3、4这5个数字组成一个圆圈,从数字0开始每次删除第3个数字,则删除的前4个数字依次是2、0、4、1,因此最后剩下的数字是3。

示例 1:

输入: n = 5, m = 3
输出: 3

示例 2:

输入: n = 10, m = 17
输出: 2
class Solution {
    public int lastRemaining(int n, int m) {
       ArrayList<Integer> list=new ArrayList<>(n);
       for(int i=0;i<n;i++){
           list.add(i);
       }
       int index=0;
       while(list.size()!=1){
         index=(m-1+index)%list.size();
         list.remove(index);
       }
       return  list.get(0);

    }
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值