算法-刷题
剑指Offer快速过了一遍
字节-飞书高频题-前15
各公司的高频面试算法题,可在 CodeTop查询
(1) 146. LRU 缓存机制
我的实现:
class LRUCache {
ArrayDeque<Integer> queue;
Map<Integer, Integer> cacheMap;
private int capacity;
private int size;
public LRUCache(int capacity) {
if (capacity < 1) {
throw new RuntimeException("capacity is error");
}
this.capacity = capacity;
queue = new ArrayDeque<>();
cacheMap = new HashMap<>();
size = 0;
}
public int get(int key) {
if (cacheMap.isEmpty()) {
return -1;
}
if (cacheMap.containsKey(key)) {
queue.remove(key);
queue.add(key);
return cacheMap.get(key);
} else {
return -1;
}
}
public void put(int key, int value) {
if (cacheMap.containsKey(key)) {
cacheMap.put(key, value);
queue.remove(key);
queue.add(key);
} else {
size ++;
if (size > capacity) {
int needDelete = queue.pop();
cacheMap.remove(needDelete);
}
cacheMap.put(key, value);
queue.add(key);
}
}
}
官方实现:
public class LRUCache {
class DLinkedNode {
int key;
int value;
DLinkedNode prev;
DLinkedNode next;
public DLinkedNode() {
}
public DLinkedNode(int _key, int _value) {
key = _key; value = _value;}
}
private Map<Integer, DLinkedNode> cache = new HashMap<Integer, DLinkedNode>();
private int size;
private int capacity;
private DLinkedNode head, tail;
public LRUCache(int capacity) {
this.size = 0;
this.capacity = capacity;
// 使用伪头部和伪尾部节点
head = new DLinkedNode();
tail = new DLinkedNode();
head.next = tail;
tail.prev = head;
}
public int get(int key) {
DLinkedNode node = cache.get(key);
if (node == null) {
return -1;
}
// 如果 key 存在,先通过哈希表定位,再移到头部
moveToHead(node);
return node.value;
}
public void put(int key, int value) {
DLinkedNode node = cache.get(key);
if (node == null) {
// 如果 key 不存在,创建一个新的节点
DLinkedNode newNode = new DLinkedNode(key, value);
// 添加进哈希表
cache.put(key, newNode);
// 添加至双向链表的头部
addToHead(newNode);
++size;
if (size > capacity) {
// 如果超出容量,删除双向链表的尾部节点
DLinkedNode tail = removeTail();
// 删除哈希表中对应的项
cache.remove(tail.key);
--size;
}
}
else {
// 如果 key 存在,先通过哈希表定位,再修改 value,并移到头部
node.value = value;
moveToHead(node);
}
}
private void addToHead(DLinkedNode node) {
node.prev = head;
node.next = head.next;
head.next.prev = node;
head.next = node;
}
private void removeNode(DLinkedNode node) {
node.prev.next = node.next;
node.next.prev = node.prev;
}
private void moveToHead(DLinkedNode node) {
removeNode(node);
addToHead(node);
}
private DLinkedNode removeTail() {
DLinkedNode res = tail.prev;
removeNode(res);
return res;
}
}
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/lru-cache/solution/lruhuan-cun-ji-zhi-by-leetcode-solution/
来源:力扣(LeetCode)
(2) 3. 无重复字符的最长子串
class Solution {
public int lengthOfLongestSubstring(String s) {
if (s == null || s.length() == 0) {
return 0;
}
int max = 0;
int left = 0;
HashMap<Character, Integer> map = new HashMap<>();
for (int i = 0; i< s.length(); i++ ) {
Character charTemp = s.charAt(i);
if (map.containsKey(charTemp)) {
left = Math.max(left, map.get(charTemp) + 1);
}
map.put(charTemp, i);
max = Math.max(max, i - left + 1);
}
return max;
}
}
(3) 206. 反转链表
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode reverseList(ListNode head) {
if (head == null || head.next == null) {
return head;
}
ListNode preNode = null;
ListNode currentNode = head;
while (currentNode != null) {
ListNode next = currentNode.next;
currentNode.next = preNode;
preNode = currentNode;
currentNode = next;
}
return preNode;
}
}
(4) 103. 二叉树的锯齿形层序遍历
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
List<List<Integer>> result = new LinkedList<List<Integer>>();
if (root == null) {
return result;
}
Deque<TreeNode> deque = new LinkedList<>();
deque.offer(root);
int currentLevel = 0;
while (!deque.isEmpty()) {
int levelSize = deque.size();
Deque<Integer> currentList = new LinkedList<>();
for (int i=0; i< levelSize; i++) {
TreeNode currentNode = deque.peek();
if (currentNode.left != null) {
deque.offer(currentNode.left);
}
if (currentNode.right != null) {
deque.offer(currentNode.right);
}
if (currentLevel % 2 == 0) {
currentList.offerLast(currentNode.val);
} else {
currentList.offerFirst(currentNode.val);
}
deque.poll();
}
currentLevel ++ ;
result.add(new LinkedList<>(currentList));
}
return result;
}
}
该题是 102.二叉树的层序遍历 的变换之后的题目,下面是 二叉树层序遍历的实现:
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> result = new LinkedList<List<Integer>>();
if (root == null) {
return result;
}
Deque<TreeNode> deque = new LinkedList<TreeNode>();
deque.offer(root);
while (!deque.isEmpty()) {
int size = deque.size();
List<Integer> currentList = new LinkedList<>();
for (int i=0; i< size; i++) {
TreeNode currentNode = deque.peek();
currentList.add(currentNode.val);
if (currentNode.left != null) {
deque.offer(currentNode.left);
}
if (currentNode.right != null) {
deque.offer(currentNode.right);
}
deque.poll();
}
result.add(currentList);
}
return result;
}
}
(5) 121.买卖股票的最佳时机
public class Solution {
/**
*暴力解法
* @param prices
* @return
*/
public int maxProfit1(int[] prices) {
int maxProfit = 0;
for (int i = 0; i<prices.length - 1; i++) {
for (int j = i+1; j < prices.length; j++) {
int currentProfit = prices[j] - prices[i];
if (currentProfit > maxProfit) {
maxProfit = currentProfit;
}
}
}
return maxProfit;
}
/**
* 非暴力
* @param prices
* @return
*/
public int maxProfit(int[] prices) {
int minPrice = Integer.MAX_VALUE;
int maxProfit = 0;
for (int i = 0; i<prices.length; i++) {
if (prices[i] < minPrice) {
minPrice = prices[i];
} else if (prices[i] - minPrice > maxProfit) {
maxProfit = prices[i] - minPrice;
}
}
return maxProfit;
}
}
(6) 41.缺失的第一个正数
class Solution {
public int firstMissingPositive(int[] nums) {
for (int i = 0; i<nums.length;i++) {
while (nums[i] >=1 && nums[i]<=nums.length && nums[i] != nums[nums[i] -1]) {
swap(nums, i, nums[i] -1);
}
}
for (int i=0;i<nums.length;i++) {
if (i != nums[i]-1) {
return i+1;
}
}
return nums.length +1;
}
private void swap(int[] nums, int i,int j) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
}
(7) 46.全排列
public class Permute {
public List<List<Integer>> permute(int[] nums) {
List<List<Integer>> result = new ArrayList<>();
if (nums == null || nums.length == 0) {
return result;
}
List<Integer> outPut = new ArrayList<>();
for (int i=0; i< nums.length; i++) {
outPut.add(nums[i]);
}
backTrack(0, nums.length, outPut, result);
return result;
}
public void backTrack(int first, int n, List<Integer> outPut, List<List<Integer>> result) {
if (first == n) {
result.add(new ArrayList<>(outPut));
}
for (int i = first; i<n; i++) {
Collections.swap(outPut, first, i);
backTrack(first+1, n, outPut, result);
Collections.swap(outPut, first, i);
}
}
}
(8) 1. 两数之和
class Solution {
public int[] twoSum(int[] nums, int target) {
HashMap<Integer, Integer> numAndIndex = new HashMap<>();
for (int i=0;i<nums.length;i++) {
int b = target - nums[i];
if (numAndIndex.containsKey(b)) {
return new int[]{
i, numAndIndex.get(b)};
}
numAndIndex.put(nums[i], i);
}
return new int[0];
}
}
(9) 128. 最长连续序列
public int longestConsecutive(int[] nums) {
HashSet<Integer> numSet = new HashSet<>();
for (int i=0; i<nums.length;i++) {
numSet.add(nums[i]);
}
int maxLength = 0;
for (int i =0;i<nums.length;i++) {
if (!numSet.contains(nums[i] - 1)) {
int currentNum = nums[i];
int currentLength = 1;
while (numSet.contains(currentNum + 1)) {
currentNum +=1;
currentLength ++;
}
maxLength = Math.max(maxLength, currentLength);
}
}
return maxLength;
}
还没有评论,来说两句吧...