412、难度简单:
改进描述基于:
作者:LeetCode
链接:https://leetcode-cn.com/problems/fizz-buzz/solution/fizz-buzz-by-leetcode/
方法一:模拟法
代码步骤:
1、首先我们需要一个初始化一个空的答案列表:
List supplierNames = new List(); 不可行原因:
List是一个Interface,不能实例化一个Interface,因为interface是一个约定,表示什么样的方法应该具有我们的类。为了实例化,需要该接口的一些实现。可以使用下面的代码以及非常流行的List接口实现:
List supplierNames = new ArrayList();
List supplierNames = new LinkedList();
2、遍历 1…N
3、按照题目规则给答案列表赋值
class Solution {
public List<String> fizzBuzz(int n) {
// ans list
List<String> ans = new ArrayList<String>();
for (int num = 1; num <= n; num++) {
boolean divisibleBy3 = (num % 3 == 0);
boolean divisibleBy5 = (num % 5 == 0);
if (divisibleBy3 && divisibleBy5) {
ans.add("FizzBuzz");
} else if (divisibleBy3) {
ans.add("Fizz");
} else if (divisibleBy5) {
ans.add("Buzz");
} else {
// 注意:这里写如下代码和写 str.add(i + 1 + ""); 在时间消耗上有很大差距
ans.add(Integer.toString(num));
}
}
return ans;
}
}
方法二:字符串连接:
这个方法不会降低渐进复杂度,但是当 FizzBuzz
的规则变得更复杂的时候,如果还是用方法一来解决这个问题的话,那将会有非常多的条件需要判断。
原理:对于 FizzBuzz
来说,运用拼接后只需要判断两个条件就可以了,而不需要像方法一中那样判断三个条件
class Solution {
public List<String> fizzBuzz(int n) {
// ans list
List<String> ans = new ArrayList<String>();
for (int num = 1; num <= n; num++) {
boolean divisibleBy3 = (num % 3 == 0);
boolean divisibleBy5 = (num % 5 == 0);
String numAnsStr = "";
if (divisibleBy3) {
numAnsStr += "Fizz";
}
if (divisibleBy5) {
numAnsStr += "Buzz";
}
// 若 numAnsStr 此时为空,说明前两个 if 都没过
if (numAnsStr.equals("")) {
numAnsStr += Integer.toString(num);
}
ans.add(numAnsStr);
}
return ans;
}
}
方法三:用散列表:
这个方法是对方法二的优化。当数字和答案的映射是定好的,那么方法二用起来也还可以。但若题目需要更自由的映射关系呢?
每个映射一个判断显然是不可行的,这样写出来的代码难以维护。
如果老板有这样一个需求,明天你把映射关系换掉或者删除一个映射关系吧。对于这种要求,那只能一个个去修改判断条件的代码。
解决措施:把映射关系放在 散列表 里面
步骤:
1、把所有的映射关系放在散列表 fizzBuzzHash 中,这个散列表形如 { 3: ‘Fizz’, 5: ‘Buzz’ }。
2、遍历 1 … N
3、对于每个数字,遍历 fizzBuzzHash 中的键,检查是否能被它整除。
4、如果这个数能被键整除,就把当前键映射的值加到到答案字符串后面去。对于散列表的每个键值对,都这样操作。
5、最后将答案字符串加入答案列表。
class Solution {
public List<String> fizzBuzz(int n) {
List<String> ans = new ArrayList<String>();
// Hash map to store all fizzbuzz mappings.
HashMap<Integer, String> fizzBizzDict =
new HashMap<Integer, String>() {
{
put(3, "Fizz");
put(5, "Buzz");
}
};
for (int num = 1; num <= n; num++) {
String numAnsStr = "";
for (Integer key : fizzBizzDict.keySet()) {
// If the num is divisible by key,
// then add the corresponding string mapping to current numAnsStr
if (num % key == 0) {
numAnsStr += fizzBizzDict.get(key);
}
}
if (numAnsStr.equals("")) {
// Not divisible by 3 or 5, add the number
numAnsStr += Integer.toString(num);
}
// Append the current answer str to the ans list
ans.add(numAnsStr);
}
return ans;
}
}
155、难度简单:
题意:我们只需设计出一个栈,然后数值的传入等都是网站在输入
要求:能在常数时间内检索到最小元素的栈
栈的特点:先进后出,新元素放入栈顶,取元素从栈顶取
/**
* Your MinStack object will be instantiated and called as such:
* MinStack obj = new MinStack();
* obj.push(val);
* obj.pop();
* int param_3 = obj.top();
* int param_4 = obj.getMin();
* 官方默认代码配置如下:
*/
class MinStack {
public MinStack() {}
public void push(int val) {}
public void pop() {}
public int top() {}
public int getMin() {}
}
方法一:辅助栈:
原理:在每个元素 a
入栈时把当前栈的最小值 m
存储起来。在这之后无论何时,如果栈顶元素是 a
,我们就可以直接返回存储的最小值 m
。按照该思路,我们只需要设计一个数据结构,使得每个元素 a 与其相应的最小值 m 时刻保持一一对应。因此我们可以使用一个辅助栈,与元素栈同步插入与删除,用于存储与每个元素对应的最小值。
当一个元素要入栈时,我们取当前辅助栈的栈顶存储的最小值,与当前元素比较得出最小值,将这个最小值插入辅助栈中;
当一个元素要出栈时,我们把辅助栈的栈顶元素也一并弹出;
在任意一个时刻,栈内元素的最小值就存储在辅助栈的栈顶元素中。
class MinStack {
// 使用Deque双端队列实现栈
// 被进行操作的栈
Deque<Integer> xStack;
// 辅助栈,用于保存对应 minStack 当前 top 元素时栈的历史最小值
Deque<Integer> minStack;
// 初始化所有栈
public MinStack() {
// 与ArrayList相比,LinkedList的增删操作效率更高,而查改操作效率较低。
xStack = new LinkedList<Integer>();
minStack = new LinkedList<Integer>();
// 给辅助栈加入最大值
minStack.push(Integer.MAX_VALUE);
}
public void push(int x) {
xStack.push(x);
// 辅助栈对当前加入值和过往最小值进行比较,选择更小值进行加入
minStack.push(Math.min(minStack.peek(), x));
}
public void pop() {
xStack.pop();
minStack.pop();
}
public int top() {
// LinkedList 的方法:返回第一个元素
return xStack.peek();
}
public int getMin() {
return minStack.peek();
}
}
对上述代码中 Deque xStack = new LinkedList(); 的解释:
Java中LinkedList
类实现了两者Deque
和List
接口
若想要实现队列,选择所需的性能,存储和访问特性的接口来实现Queue
,例如
LinkedList
使用更多内存,但在清空队列时收缩。ArrayDeque
使用较少的内存,但它不会缩小。PriorityQueue
是一个具有元素优先级的非FIFO队列。ConcurrentLinkedQueue
,ConcurrentLinkedDeque
支持多线程并发访问。- 和更多…