当前位置:网站首页>Day36 LeetCode
Day36 LeetCode
2022-08-10 07:48:00 【太阳在坠落】
1. 函数的独占时间
有一个 单线程 CPU 正在运行一个含有 n 道函数的程序。每道函数都有一个位于 0 和 n-1 之间的唯一标识符。
函数调用 存储在一个 调用栈 上 :当一个函数调用开始时,它的标识符将会推入栈中。而当一个函数调用结束时,它的标识符将会从栈中弹出。标识符位于栈顶的函数是 当前正在执行的函数 。每当一个函数开始或者结束时,将会记录一条日志,包括函数标识符、是开始还是结束、以及相应的时间戳。
给你一个由日志组成的列表 logs ,其中 logs[i] 表示第 i 条日志消息,该消息是一个按 “{function_id}:{“start” | “end”}:{timestamp}” 进行格式化的字符串。例如,“0:start:3” 意味着标识符为 0 的函数调用在时间戳 3 的 起始开始执行 ;而 “1:\end:2” 意味着标识符为 1 的函数调用在时间戳 2 的 末尾结束执行。注意,函数可以 调用多次,可能存在递归调用 。
函数的 独占时间 定义是在这个函数在程序所有函数调用中执行时间的总和,调用其他函数花费的时间不算该函数的独占时间。例如,如果一个函数被调用两次,一次调用执行 2 单位时间,另一次调用执行 1 单位时间,那么该函数的 独占时间 为 2 + 1 = 3 。
以数组形式返回每个函数的 独占时间 ,其中第 i 个下标对应的值表示标识符 i 的函数的独占时间。
分析:
使用栈来模拟执行过程:当一个函数被调用(op = start)时,压入栈内,当函数调用完成(op = end)时,从栈顶弹出(此时栈顶元素必然是该结束函数的入栈记录),使用变量 cur 记录当前时间。
从前往后处理所有的 log[i],根据 log[i]是属于函数调用还是函数结束进行分情况讨论:
- 当 log[i] 为函数调用:此时从该函数的调用发起时间 ts 到上一次记录的当前时间,都是前一函数的执行时间,因此可以将 ts - cur 累加到栈帧中的前一函数。即若栈不为空,则将该时间累加到栈顶对应的函数上,然后将 log[i] 入栈,同时更新当前时间;
- 当 log[i] 为函数结束:此时栈顶元素必然是该函数的调用记录,此时 log[i] 的结束时间与上一次记录的当前时间的时长 ts - cur + 1,必然是该函数的执行时间,将其累加到当前函数中,并更新当前时间。
class Solution {
public int[] exclusiveTime(int n, List<String> logs) {
int[] ans = new int[n];
Deque<Integer> d = new ArrayDeque<>();
int cur = -1;
for (String log : logs) {
String[] ss = log.split(":");
int idx = Integer.parseInt(ss[0]), ts = Integer.parseInt(ss[2]);
if (ss[1].equals("start")) {
if (!d.isEmpty()) ans[d.peekLast()] += ts - cur;
d.addLast(idx);
cur = ts;
} else {
int func = d.pollLast();
ans[func] += ts - cur + 1;
cur = ts + 1;
}
}
return ans;
}
}
2. 房屋偷盗
一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响小偷偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。
给定一个代表每个房屋存放金额的非负整数数组 nums ,请计算 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。
分析:
动态规划。定义数组dp,dp[i]表示第i-1天可以偷窃到的最高金额,初始化dp[0]=nums[0], dp[1]=max(nums[0], nums[1]),递推公式为dp[n] = max(nums[n]+dp[n-2], dp[n-1])
class Solution {
public int rob(int[] nums) {
if (nums.length == 0) return 0;
if (nums.length == 1) return nums[0];
int[] dp = new int[nums.length];
dp[0] = nums[0];
dp[1] = Math.max(nums[0], nums[1]);
for (int i = 2; i < nums.length; i++) {
dp[i] = Math.max(nums[i]+dp[i-2], dp[i - 1]);
}
return dp[nums.length-1];
}
}
3. 特殊的二进制序列
特殊的二进制序列是具有以下两个性质的二进制序列:
- 0 的数量与 1 的数量相等。
- 二进制序列的每一个前缀码中 1 的数量要大于等于 0 的数量。
给定一个特殊的二进制序列 S,以字符串形式表示。定义一个操作为首先选择 S 的两个连续且非空的特殊的子串,然后将它们交换。(两个子串为连续的当且仅当第一个子串的最后一个字符恰好为第二个子串的第一个字符的前一个字符。)
在任意次数的操作之后,交换后的字符串按照字典序排列的最大的结果是什么?
分析:
由于具备的两个性质可得:序列的第一个数一定是1,最后一个数一定是0;任意前缀中 1 的数量一定大于等于 0 的数量。
由此定义每个字符的得分:字符 1 得分为 1 分,字符 0 得分为 -1 分。给定字符串 s 的总得分为 0,且任意前缀串不会出现得分为负数的情况。考虑将 s 进行划分为多个足够小特殊字符串 item(足够小的含义为每个 item 无法再进行划分),每个 item 的总得分为 0。根据 s 定义,必然可恰好划分为多个 item。每次操作可以将相邻特殊字符串进行交换,于是问题转换为将 s 进行重排,求其重排后字典序最大的方案。
class Solution {
public String makeLargestSpecial(String s) {
if (s.length() == 0) return "";
List<String> list = new ArrayList<>();
int count = 0, last = 0;
for (int i = 0, cur=0; i < s.length(); i++, cur++) {
if (s.charAt(i) == '1') count++;
else count--;
if (count == 0){
String string = "1" + makeLargestSpecial(s.substring(last+1, cur))+"0";
list.add(string);
last = cur+1;
}
}
list.sort(Comparator.reverseOrder());
StringBuffer sb = new StringBuffer();
for (String s1 : list) {
sb.append(s1);
}
return sb.toString();
}
}
4. 有效的变位词
给定两个字符串 s 和 t ,编写一个函数来判断它们是不是一组变位词(字母异位词)。
注意:若 s 和 t 中每个字符出现的次数都相同且字符顺序不完全相同,则称 s 和 t 互为变位词(字母异位词)。
分析:
首先要判断s != t,然后统计各自字符串中字母出现的次数,判断是否相等。
public boolean isAnagram(String s, String t) {
if (s.length() != t.length()) return false;
if (s.equals(t)) return false;
int[] a = new int[26];
int[] b = new int[26];
for (int i = 0; i < s.length(); i++) {
a[s.charAt(i) - 'a']++;
b[t.charAt(i) - 'a']++;
}
return Arrays.equals(a, b);
}
5. 变位词组
给定一个字符串数组 strs ,将 变位词 组合在一起。 可以按任意顺序返回结果列表。
注意:若两个字符串中每个字符出现的次数都相同,则称它们互为变位词。
分析:
首先定义一个map用来存储字母组合以及其该字母组合的字符串。遍历strs,每得到一个str首先对其排序得到对应的key,然后把(key,str)存入map。最后返回map的每个value。
class Solution {
public List<List<String>> groupAnagrams(String[] strs) {
if (strs.length == 0) return null;
HashMap<String, List<String>> map = new HashMap<>();
for (String str : strs){
char[] chars = str.toCharArray();
Arrays.sort(chars);
String key = Arrays.toString(chars);
List<String> value = map.getOrDefault(key, new ArrayList<>());
value.add(str);
map.put(key, value);
}
return new ArrayList<List<String>>(map.values());
}
}
边栏推荐
- mysql数据库月增长量问题
- The probability distribution and its application
- 模糊查询除了like+ % 还能用什么方式
- 阿里云数据库 RDS SQL Server 版的服务器绑定域名www.cxsdkt.cn.的呢?
- SQL SERVER 数据库,表的数据发生增删改,该表的索引会在ldf日志中记录吗?
- Add spark related dependencies and packaging plugins (sixth bullet)
- In the SQL SERVER database, if the data of the table is added, deleted, or modified, will the index of the table be recorded in the ldf log?
- MySQL设置初始密码—注意版本mysql-8.0.30
- 【转】探秘钉钉的即时消息服务DTIM
- 【Event Preview on August 9】Prometheus Summit
猜你喜欢
DGIOT三千万电表集抄压测
VS2013-debug assembly code-generate asm file-structure memory layout-function parameter stack-calling convention
基于STC8G2K64S4单片机通过OLED屏幕显示模拟量光敏模拟值
90.(cesium之家)cesium高度监听事件
每日一题,二叉树中增加一行
Nude speech - lying flat - brushing questions - big factory (several tips for Android interviews)
Uni-app开发微信小程序使用本地图片做背景图
快速输入当前日期与时间
力扣(LeetCode)221. 最大正方形(2022.08.09)
深入理解LTE网络的CDRX
随机推荐
NPU架构与算力分析
颜色选择器的使用
上课笔记(7)(1)——#647. 找树根和孩子(root)
幂函数 指数函数 对数函数
QT下载清华源配置
个人博客系统
If the data of the oracle business table is added, deleted, or modified, will the index of the table write redo and undo?
u-boot ERROR: Failed to allocate 0x5c6f bytes below 0x17ffffff.Failed using fdt_high value
34. Talk about why you want to split the database?What methods are there?
ctfshow SSTI 知识点总结
【转】探秘钉钉的即时消息服务DTIM
What is an MQTT gateway?What is the difference with traditional DTU?
WooCommerce 安装和 rest api 使用
SQL建表问题,帮我看看好吗朋友们~大家人。!
大佬,oracle单表增量同步时候源库服务器额外占用内存近2g,这不正常吧
MySQL database monthly growth problem
NPU architecture and force analysis
简单业务类
第十六天&charles的基本操作
Bigder:42/100 showCase多少bug可以打回去