第一个题目如下:
给你一组字符串,由英文和(),<构成,()圈起来的部分是注释,不会输出,‘<’是删除,会把有效输出删除,()保证成对出现,<不会影响到括号,求有效输出 输入: 一行字符串,例如a<<b(a(<)) 输出: 最终的有效字符 b
代码如下:
package algorithm;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.Scanner;
import java.util.Stack;
public class OutputValidChar {
public static void main(String[] args) {
Stack<Character> stack = new Stack<>();
Deque<Character> deque = new ArrayDeque<>();
//Scanner sc = new Scanner(System.in);
//String s = sc.next();
String str = "a<<mb(a(<))";
for (int i = 0; i < str.length(); i++) {
Character currentChar = str.charAt(i);
if(currentChar=='<'){
if(deque.size()>0 && stack.isEmpty()){
deque.clear();
}
} else if (currentChar=='(') {
stack.push('(');
} else if (currentChar==')') {
stack.pop();
}else {
if(stack.isEmpty()){
deque.add(currentChar);
}
}
}
while (deque.size()>0){
System.out.print(deque.poll());
}
}
}
运行结果
第二个题目如下:
给一个字符串str,和n个字符,求str中包含n个字符的最短子串
代码如下
package algorithm;
import java.util.HashMap;
import java.util.Map;
public class MinAverageSubStr {
public static void main(String[] args) {
String str = "ADOBECODEBANC";
char[] chars = {'A', 'B', 'C'};
System.out.println(getSubStr(str, chars)); // Output: "BANC"
}
public static String getSubStr(String originStr, char[] chars) {
int left = 0;
int right = 0;
int subStrLength = Integer.MAX_VALUE;
int charCount = 0;
String subStr = "";
Map<Character, Integer> charMap = new HashMap<>();
for (Character c : chars) {
charMap.put(c, 0);
}
while (right < originStr.length()) {
Character currentChar = originStr.charAt(right);
if (charMap.containsKey(currentChar)) {
if (charMap.get(currentChar) == 0) {
charCount++;
}
charMap.put(currentChar, charMap.get(currentChar) + 1);
}
while (charCount == chars.length) {
if (right - left + 1 < subStrLength) {
subStrLength = right - left + 1;
subStr = originStr.substring(left, right + 1);
}
Character leftChar = originStr.charAt(left);
if (charMap.containsKey(leftChar)) {
charMap.put(leftChar, charMap.get(leftChar) - 1);
if (charMap.get(leftChar) == 0) {
charCount--;
}
}
left++;
}
right++;
}
return subStr;
}
}
运行结果如下图
第三个题目如下:
手写一个LRU算法,不能使用LinkedList。
说明:LRU(Least recently used,最近最少使用)算法根据数据的历史访问记录来进行淘汰数据,其核心思想是“如果数据最近被访问过,那么将来被访问的几率也更高”
package algorithm;
import java.util.HashMap;
import java.util.Map;
public class LeastRecentlyUsed <K,V>{
private int capacity;
private Map<K,Node<K,V>> nodeMap;
private Node<K,V> head;
private Node<K,V> tail;
public LeastRecentlyUsed(int capacity){
this.capacity = capacity;
this.nodeMap = new HashMap<>();
this.head = new Node<>(null,null);
this.tail = new Node<>(null,null);
head.next = tail;
tail.prev = head;
}
private void put(K key,V value){
Node cacheNode = nodeMap.get(key);
if (cacheNode == null) {
if (nodeMap.size() == capacity) {
deleteTailNode(tail);
}
Node node = new Node<>(key,value);
addToHead(node);
nodeMap.put(key, node);
} else {
cacheNode.value = value;
moveToHead(cacheNode);
}
}
private void moveToHead(Node<K,V> node){
removeNode(node);
addToHead(node);
}
private void addToHead(Node<K,V> node){
head.next.prev = node;
node.next = head.next;
node.prev = head;
head.next = node;
}
private void deleteTailNode(Node<K,V> tail){
Node<K,V> lastNode = tail.prev;
removeNode(lastNode);
nodeMap.remove(lastNode.key);
}
private void removeNode(Node<K,V> node){
node.prev.next = node.next;
node.next.prev = node.prev;
}
private Node get(K key){
Node cacheNode = nodeMap.get(key);
if (cacheNode != null) {
moveToHead(cacheNode);
return cacheNode;
}
return null;
}
static class Node<K,V>{
K key;
V value;
Node<K,V> prev;
Node<K,V> next;
Node(K key,V value){
this.key = key;
this.value = value;
}
public V getValue(){
return this.value;
}
}
public static void main(String[] args) {
LeastRecentlyUsed<String, String> lruCache = new LeastRecentlyUsed(5);
lruCache.put("key1", "value1");
lruCache.put("key2", "value2");
lruCache.put("key3", "value3");
lruCache.put("key4", "value4");
lruCache.put("key5", "value5");
lruCache.put("key6", "value6");
Map<String, LeastRecentlyUsed.Node<String, String>> cache = lruCache.nodeMap;
for (String key : cache.keySet()) {
LeastRecentlyUsed.Node<String, String> node = cache.get(key);
System.out.println(node.key + ":" + node.value);
}
System.out.println("执行get操作前,首节点信息如下---------------------");
Node<String,String> firstNode = lruCache.head.next;
System.out.println(firstNode.key+":"+firstNode.value);
lruCache.get("key3");
System.out.println("执行get操作后,首节点信息如下---------------------");
Node<String,String> firstNodeInfo = lruCache.head.next;
System.out.println(firstNodeInfo.key+":"+firstNodeInfo.value);
}
}
运行结果如下图
第四个题目如下
给定两个字符串形式的非负整数
num1
和num2
,计算它们的和并同样以字符串形式返回。你不能使用任何內建的用于处理大整数的库(比如
BigInteger
), 也不能直接将输入的字符串转换为整数形式。
package algorithm;
public class StringAdd {
public static void main(String[] args) {
System.out.println(stringAdd("456", "99"));
}
public static String stringAdd(String text1, String text2) {
StringBuilder sb = new StringBuilder();
int i = text1.length() - 1;
int j = text2.length() - 1;
int carryValue = 0;
while (i >= 0 || j >= 0 || carryValue > 0) {
int num1 = i >= 0 ? text1.charAt(i) - '0' : 0;
int num2 = j >= 0 ? text2.charAt(j) - '0' : 0;
int sum = num1 + num2 + carryValue;
carryValue = sum / 10;
int result = sum % 10;
sb.insert(0, result);
i--;
j--;
}
return sb.toString();
}
}
运行结果如下图: