每日一题:力扣636函数的独占时间
思路一:使用:循环,Character.isDigit()方法(判断字符书否为数字)。
思路二:栈(来源:力扣)
思路与算法
我们可以用栈来模拟函数调用的过程,栈顶的元素为当前正在执行函数:
- 当函数调用开始时,如果当前有函数正在运行,则当前正在运行函数应当停止,此时计算其的执行时间,然后将调用函数入栈。
- 当函数调用结束时,将栈顶元素弹出,并计算相应的执行时间,如果此时栈顶有被暂停的函数,则开始运行该函数。
由于每一个函数都有一个对应的 start 和 end 日志,且当遇到一个 endendend 日志时,栈顶元素一定为其对应的 start 日志。那么我们对于每一个函数记录它的函数标识符和上次开始运行的时间戳,此时我们只需要在每次函数暂停运行的时候来计算执行时间和开始运行的时候更新时间戳即可。
class Solution {
public int[] exclusiveTime(int n, List<String> logs) {
Deque<int[]> stack = new ArrayDeque<int[]>(); // {idx, 开始运行的时间}
int[] res = new int[n];
for (String log : logs) {
int idx = Integer.parseInt(log.substring(0, log.indexOf(':')));
String type = log.substring(log.indexOf(':') + 1, log.lastIndexOf(':'));
int timestamp = Integer.parseInt(log.substring(log.lastIndexOf(':') + 1));
if ("start".equals(type)) {
if (!stack.isEmpty()) {
res[stack.peek()[0]] += timestamp - stack.peek()[1];
stack.peek()[1] = timestamp;
}
stack.push(new int[]{idx, timestamp});
} else {
int[] t = stack.pop();
res[t[0]] += timestamp - t[1] + 1;
if (!stack.isEmpty()) {
stack.peek()[1] = timestamp + 1;
}
}
}
return res;
}
}
1.Deque
Deque是一个双端队列接口,继承自Queue接口,Deque的实现类是LinkedList、ArrayDeque、LinkedBlockingDeque,其中LinkedList是最常用的
Deque的三种用途:
1.普通队列(一端进另一端出):
Queue queue = new LinkedList()或Deque deque = new LinkedList()
2.双端队列(两端都可进出)
Deque deque = new LinkedList()
3.堆栈
Deque deque = new LinkedList()
2.Integer.parseInt()
将字符串解析为带参数的数字
2.SpringBoot自动装配
在启动类上有注解--> @SpringBootApplication,该注解包含注解--> @EnableAutoConfiguration,即是与自动装配相关的注解,跟进该注解,其中会发现名为:@Import(),该注解在Spring中多用在spring的配置类上,用于将多个配置类配置合为一处,而我们的启动类中因为有注解@SpringBootConfiguration,该类本就是一个配置类
@Import()的参数为 AutoConfigurationImportSelector.class,也就是说,我们的启动类,引入了这个类,进入类AutoConfigurationImportSelector 我们可以看到
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {
private static final AutoConfigurationEntry EMPTY_ENTRY = new AutoConfigurationEntry();
private static final String[] NO_IMPORTS = {};
private static final Log logger = LogFactory.getLog(AutoConfigurationImportSelector.class);
private static final String PROPERTY_NAME_AUTOCONFIGURE_EXCLUDE = "spring.autoconfigure.exclude";
private ConfigurableListableBeanFactory beanFactory;
private Environment environment;
private ClassLoader beanClassLoader;
private ResourceLoader resourceLoader;
private ConfigurationClassFilter configurationClassFilter;
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
if (!isEnabled(annotationMetadata)) {
return NO_IMPORTS;
}
AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(annotationMetadata);
return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}
该类继承了类 DeferredImportSelector,而DeferredImportSelector类继承了类ImportSelector,因此我们的 AutoConfigurationImportSelector必定重写了方法 selectimports()方法,关键也就在于该方法,我们看该行代码:
AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(annotationMetadata);
就是说方法selectimports() 会调用本类方法getAutoConfigurationEntry(annotationMetadata),
protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
if (!isEnabled(annotationMetadata)) {
return EMPTY_ENTRY;
}
AnnotationAttributes attributes = getAttributes(annotationMetadata);
List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
configurations = removeDuplicates(configurations);
Set<String> exclusions = getExclusions(annotationMetadata, attributes);
checkExcludedClasses(configurations, exclusions);
configurations.removeAll(exclusions);
configurations = getConfigurationClassFilter().filter(configurations);
fireAutoConfigurationImportEvents(configurations, exclusions);
return new AutoConfigurationEntry(configurations, exclusions);
}
在该方法中,加载META-INF/spring-autoconfigure-metadata.properties 下的元数据信息,对该信息进行去充,排序,去除不需要的信息最后返回AutoConfigurationEntry。