【每日一题见微知著】模拟题(股票价格波动)+力扣周赛题

⭐️寒假新坑——代码之狐的每日做题笔记

2034. 股票价格波动

题目描述:

给你一支股票价格的数据流。数据流中每一条记录包含一个 时间戳 和该时间点股票对应的 价格

不巧的是,由于股票市场内在的波动性,股票价格记录可能不是按时间顺序到来的。某些情况下,有的记录可能是错的。如果两个有相同时间戳的记录出现在数据流中,前一条记录视为错误记录,后出现的记录 更正 前一条错误的记录。

请你设计一个算法,实现:

  • 更新 股票在某一时间戳的股票价格,如果有之前同一时间戳的价格,这一操作将 更正 之前的错误价格。
  • 找到当前记录里 最新股票价格最新股票价格 定义为时间戳最晚的股票价格。
  • 找到当前记录里股票的 最高价格
  • 找到当前记录里股票的 最低价格

请你实现 StockPrice 类:

  • StockPrice() 初始化对象,当前无股票价格记录。
  • void update(int timestamp, int price) 在时间点 timestamp 更新股票价格为 price
  • int current() 返回股票 最新价格
  • int maximum() 返回股票 最高价格
  • int minimum() 返回股票 最低价格
解题思路:

模拟题——利用HashMap保存时间戳和股票价格,利用一个有序数组实现更新最大最小值,一个int保存最新的时间戳——对TreeMap的使用

class StockPrice {
    int maxTimestamp;
    
    //保存 时间戳-股票价格 信息
    HashMap<Integer, Integer> timePriceMap;
    
    //自然根据key值排序(保存 股票价格-该价格出现多少次 的键值对)
    TreeMap<Integer, Integer> prices;

    public StockPrice() {
        maxTimestamp = 0;
        timePriceMap = new HashMap<Integer, Integer>();
        prices = new TreeMap<Integer, Integer>();
    }
    
    public void update(int timestamp, int price) {
        //更新最新时间戳
        maxTimestamp = Math.max(maxTimestamp, timestamp);
        //获取当前时间戳的错误股票价格(如果为0表示该时间戳第一次出现)
        int prevPrice = timePriceMap.getOrDefault(timestamp, 0);
        //更新时间戳-股票价格
        timePriceMap.put(timestamp, price);
        
        //股票价格更新对有序map的影响
        if (prevPrice > 0) {
            //当前被修改的错误股票价格可能存在多个时间戳指向,但是只修改一个
            prices.put(prevPrice, prices.get(prevPrice) - 1);
            //如果该价格被修改后,不在存在,移除有序map中
            if (prices.get(prevPrice) == 0) {
                prices.remove(prevPrice);
            }
        }
        //加入新价格
        prices.put(price, prices.getOrDefault(price, 0) + 1);
    }
    
    public int current() {
        return timePriceMap.get(maxTimestamp);
    }
    
    public int maximum() {
        return prices.lastKey();
    }
    
    public int minimum() {
        return prices.firstKey();
    }
}

5989. 元素计数—周赛题1

给你一个整数数组 nums ,统计并返回在 nums 中同时具有一个严格较小元素和一个严格较大元素的元素数目。

class Solution {
    public int countElements(int[] nums) {
        if(nums.length<=2){
            return 0;
        }
        
        Arrays.sort(nums);
        int min=nums[0];
        int max=nums[nums.length-1];
        int ans=0;
        for(int i=0;i<nums.length;i++){
            if(nums[i]>min&&nums[i]<max){
                ans++;
            }
        }
        return ans;
    }
}

5991. 按符号重排数组-周赛题2

给你一个下标从 0 开始的整数数组 nums ,数组长度为 偶数 ,由数目相等的正整数和负整数组成。

你需要 重排 nums 中的元素,使修改后的数组满足下述条件:

  1. 任意 连续 的两个整数 符号相反
  2. 对于符号相同的所有整数,保留 它们在 nums 中的 顺序
  3. 重排后数组以正整数开头。

重排元素满足上述条件后,返回修改后的数组。

class Solution {
    public int[] rearrangeArray(int[] nums) {
        int[] ans=new int[nums.length];
        int z=0;
        int f=0;
        int cur=0;
        while(z<nums.length&&f<nums.length){
            while(z<nums.length&&nums[z]<0){
                z++;
            }
            while(f<nums.length&&nums[f]>0){
                f++;
            }
            if(z>=nums.length&&f>=nums.length){
                break;
            }
            ans[cur++]=nums[z];
            ans[cur++]=nums[f];
            
            z++;
            f++;
        }
        if(z<nums.length){
            while(z<nums.length&&nums[z]<0){
                z++;
            }
            if(z<nums.length){
                ans[cur++]=nums[z];
            }
            
        }
        if(f<nums.length){
            while(f<nums.length&&nums[f]>0){
                f++;
            }
            if(f<nums.length){
                ans[cur++]=nums[f];
            }
        }
        return ans;
    }
}

5990. 找出数组中的所有孤独数字-周赛题3

给你一个整数数组 nums 。如果数字 x 在数组中仅出现 一次 ,且没有 相邻 数字(即,x + 1x - 1)出现在数组中,则认为数字 x孤独数字

返回 nums 中的 所有 孤独数字。你可以按 任何顺序 返回答案。

class Solution {
    public List<Integer> findLonely(int[] nums) {
        List<Integer> list=new ArrayList<>();
        Map<Integer,Integer> map=new HashMap<>();
        for(int i:nums){
            map.put(i,map.getOrDefault(i,0)+1);
        }
        for(int i:nums){
            if(map.get(i-1)!=null||map.get(i+1)!=null||map.get(i)>1){
                ;
            }
            else{
                list.add(i);
            }
        }
        return list;
    }
}

5992. 基于陈述统计最多好人数-周赛题4

游戏中存在两种角色:

  • 好人:该角色只说真话。
  • 坏人:该角色可能说真话,也可能说假话。

给你一个下标从 0 开始的二维整数数组 statements ,大小为 n x n ,表示 n 个玩家对彼此角色的陈述。具体来说,statements[i][j] 可以是下述值之一:

  • 0 表示 i 的陈述认为 j坏人
  • 1 表示 i 的陈述认为 j好人
  • 2 表示 i 没有对 j 作出陈述。

另外,玩家不会对自己进行陈述。形式上,对所有 0 <= i < n ,都有 statements[i][i] = 2

根据这 n 个玩家的陈述,返回可以认为是 好人最大 数目。

class Solution {
	public int maximumGood(int[][] statements) {
        //记录好人数量
		int max = 0;
        //全可能性,用1代表假设的好人,0表示不确定
		for (int i = 0; i < 1 << statements.length; i++) {
            //如果逻辑自洽(即假设成立)
			if (maximumGood(i, statements)) {
				if (Integer.bitCount(i) == 4) {
					System.out.println(Integer.toBinaryString(i));
				}
                //统计1(代表好人)的个数
				max = Math.max(max, Integer.bitCount(i));
			}
		}
		return max;
	}

    //判断是否假设成立
	private boolean maximumGood(int mask, int[][] statements) {
        //历遍每个人的描述,对于假设的好人,判断他的话是否与做出的假设矛盾
		for (int i = 0; i < statements.length; i++) {
            //如果假设为好人
			if ((mask & 1 << i) > 0) {
				for (int j = 0; j < statements.length; j++) {
					if (statements[i][j] < 2 && (mask & 1 << j) > 0 != statements[i][j] > 0) {
						return false;
					}
				}
			}
		}
		return true;
	}
}

结尾

题目来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems

⭐️关注作者,带你刷题,从简单的算法题了解最常用的算法技能(寒假每日一题)
⭐️关注作者刷题——简单到进阶,让你不知不觉成为无情的刷题机器,有问题请私信

你可能感兴趣的:(算法与数据结构,leetcode,算法,力扣,周赛)