算法-刷题

桃扇骨 2022-09-09 02:26 292阅读 0赞

剑指Offer快速过了一遍

字节-飞书高频题-前15

各公司的高频面试算法题,可在 CodeTop查询

(1) 146. LRU 缓存机制

我的实现:

  1. class LRUCache {
  2. ArrayDeque<Integer> queue;
  3. Map<Integer, Integer> cacheMap;
  4. private int capacity;
  5. private int size;
  6. public LRUCache(int capacity) {
  7. if (capacity < 1) {
  8. throw new RuntimeException("capacity is error");
  9. }
  10. this.capacity = capacity;
  11. queue = new ArrayDeque<>();
  12. cacheMap = new HashMap<>();
  13. size = 0;
  14. }
  15. public int get(int key) {
  16. if (cacheMap.isEmpty()) {
  17. return -1;
  18. }
  19. if (cacheMap.containsKey(key)) {
  20. queue.remove(key);
  21. queue.add(key);
  22. return cacheMap.get(key);
  23. } else {
  24. return -1;
  25. }
  26. }
  27. public void put(int key, int value) {
  28. if (cacheMap.containsKey(key)) {
  29. cacheMap.put(key, value);
  30. queue.remove(key);
  31. queue.add(key);
  32. } else {
  33. size ++;
  34. if (size > capacity) {
  35. int needDelete = queue.pop();
  36. cacheMap.remove(needDelete);
  37. }
  38. cacheMap.put(key, value);
  39. queue.add(key);
  40. }
  41. }
  42. }

官方实现:

  1. public class LRUCache {
  2. class DLinkedNode {
  3. int key;
  4. int value;
  5. DLinkedNode prev;
  6. DLinkedNode next;
  7. public DLinkedNode() {
  8. }
  9. public DLinkedNode(int _key, int _value) {
  10. key = _key; value = _value;}
  11. }
  12. private Map<Integer, DLinkedNode> cache = new HashMap<Integer, DLinkedNode>();
  13. private int size;
  14. private int capacity;
  15. private DLinkedNode head, tail;
  16. public LRUCache(int capacity) {
  17. this.size = 0;
  18. this.capacity = capacity;
  19. // 使用伪头部和伪尾部节点
  20. head = new DLinkedNode();
  21. tail = new DLinkedNode();
  22. head.next = tail;
  23. tail.prev = head;
  24. }
  25. public int get(int key) {
  26. DLinkedNode node = cache.get(key);
  27. if (node == null) {
  28. return -1;
  29. }
  30. // 如果 key 存在,先通过哈希表定位,再移到头部
  31. moveToHead(node);
  32. return node.value;
  33. }
  34. public void put(int key, int value) {
  35. DLinkedNode node = cache.get(key);
  36. if (node == null) {
  37. // 如果 key 不存在,创建一个新的节点
  38. DLinkedNode newNode = new DLinkedNode(key, value);
  39. // 添加进哈希表
  40. cache.put(key, newNode);
  41. // 添加至双向链表的头部
  42. addToHead(newNode);
  43. ++size;
  44. if (size > capacity) {
  45. // 如果超出容量,删除双向链表的尾部节点
  46. DLinkedNode tail = removeTail();
  47. // 删除哈希表中对应的项
  48. cache.remove(tail.key);
  49. --size;
  50. }
  51. }
  52. else {
  53. // 如果 key 存在,先通过哈希表定位,再修改 value,并移到头部
  54. node.value = value;
  55. moveToHead(node);
  56. }
  57. }
  58. private void addToHead(DLinkedNode node) {
  59. node.prev = head;
  60. node.next = head.next;
  61. head.next.prev = node;
  62. head.next = node;
  63. }
  64. private void removeNode(DLinkedNode node) {
  65. node.prev.next = node.next;
  66. node.next.prev = node.prev;
  67. }
  68. private void moveToHead(DLinkedNode node) {
  69. removeNode(node);
  70. addToHead(node);
  71. }
  72. private DLinkedNode removeTail() {
  73. DLinkedNode res = tail.prev;
  74. removeNode(res);
  75. return res;
  76. }
  77. }
  78. 作者:LeetCode-Solution
  79. 链接:https://leetcode-cn.com/problems/lru-cache/solution/lruhuan-cun-ji-zhi-by-leetcode-solution/
  80. 来源:力扣(LeetCode

(2) 3. 无重复字符的最长子串

  1. class Solution {
  2. public int lengthOfLongestSubstring(String s) {
  3. if (s == null || s.length() == 0) {
  4. return 0;
  5. }
  6. int max = 0;
  7. int left = 0;
  8. HashMap<Character, Integer> map = new HashMap<>();
  9. for (int i = 0; i< s.length(); i++ ) {
  10. Character charTemp = s.charAt(i);
  11. if (map.containsKey(charTemp)) {
  12. left = Math.max(left, map.get(charTemp) + 1);
  13. }
  14. map.put(charTemp, i);
  15. max = Math.max(max, i - left + 1);
  16. }
  17. return max;
  18. }
  19. }

(3) 206. 反转链表

  1. /**
  2. * Definition for singly-linked list.
  3. * public class ListNode {
  4. * int val;
  5. * ListNode next;
  6. * ListNode() {}
  7. * ListNode(int val) { this.val = val; }
  8. * ListNode(int val, ListNode next) { this.val = val; this.next = next; }
  9. * }
  10. */
  11. class Solution {
  12. public ListNode reverseList(ListNode head) {
  13. if (head == null || head.next == null) {
  14. return head;
  15. }
  16. ListNode preNode = null;
  17. ListNode currentNode = head;
  18. while (currentNode != null) {
  19. ListNode next = currentNode.next;
  20. currentNode.next = preNode;
  21. preNode = currentNode;
  22. currentNode = next;
  23. }
  24. return preNode;
  25. }
  26. }

(4) 103. 二叉树的锯齿形层序遍历

  1. /**
  2. * Definition for a binary tree node.
  3. * public class TreeNode {
  4. * int val;
  5. * TreeNode left;
  6. * TreeNode right;
  7. * TreeNode() {}
  8. * TreeNode(int val) { this.val = val; }
  9. * TreeNode(int val, TreeNode left, TreeNode right) {
  10. * this.val = val;
  11. * this.left = left;
  12. * this.right = right;
  13. * }
  14. * }
  15. */
  16. class Solution {
  17. public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
  18. List<List<Integer>> result = new LinkedList<List<Integer>>();
  19. if (root == null) {
  20. return result;
  21. }
  22. Deque<TreeNode> deque = new LinkedList<>();
  23. deque.offer(root);
  24. int currentLevel = 0;
  25. while (!deque.isEmpty()) {
  26. int levelSize = deque.size();
  27. Deque<Integer> currentList = new LinkedList<>();
  28. for (int i=0; i< levelSize; i++) {
  29. TreeNode currentNode = deque.peek();
  30. if (currentNode.left != null) {
  31. deque.offer(currentNode.left);
  32. }
  33. if (currentNode.right != null) {
  34. deque.offer(currentNode.right);
  35. }
  36. if (currentLevel % 2 == 0) {
  37. currentList.offerLast(currentNode.val);
  38. } else {
  39. currentList.offerFirst(currentNode.val);
  40. }
  41. deque.poll();
  42. }
  43. currentLevel ++ ;
  44. result.add(new LinkedList<>(currentList));
  45. }
  46. return result;
  47. }
  48. }

该题是 102.二叉树的层序遍历 的变换之后的题目,下面是 二叉树层序遍历的实现:

  1. class Solution {
  2. public List<List<Integer>> levelOrder(TreeNode root) {
  3. List<List<Integer>> result = new LinkedList<List<Integer>>();
  4. if (root == null) {
  5. return result;
  6. }
  7. Deque<TreeNode> deque = new LinkedList<TreeNode>();
  8. deque.offer(root);
  9. while (!deque.isEmpty()) {
  10. int size = deque.size();
  11. List<Integer> currentList = new LinkedList<>();
  12. for (int i=0; i< size; i++) {
  13. TreeNode currentNode = deque.peek();
  14. currentList.add(currentNode.val);
  15. if (currentNode.left != null) {
  16. deque.offer(currentNode.left);
  17. }
  18. if (currentNode.right != null) {
  19. deque.offer(currentNode.right);
  20. }
  21. deque.poll();
  22. }
  23. result.add(currentList);
  24. }
  25. return result;
  26. }
  27. }

(5) 121.买卖股票的最佳时机

  1. public class Solution {
  2. /**
  3. *暴力解法
  4. * @param prices
  5. * @return
  6. */
  7. public int maxProfit1(int[] prices) {
  8. int maxProfit = 0;
  9. for (int i = 0; i<prices.length - 1; i++) {
  10. for (int j = i+1; j < prices.length; j++) {
  11. int currentProfit = prices[j] - prices[i];
  12. if (currentProfit > maxProfit) {
  13. maxProfit = currentProfit;
  14. }
  15. }
  16. }
  17. return maxProfit;
  18. }
  19. /**
  20. * 非暴力
  21. * @param prices
  22. * @return
  23. */
  24. public int maxProfit(int[] prices) {
  25. int minPrice = Integer.MAX_VALUE;
  26. int maxProfit = 0;
  27. for (int i = 0; i<prices.length; i++) {
  28. if (prices[i] < minPrice) {
  29. minPrice = prices[i];
  30. } else if (prices[i] - minPrice > maxProfit) {
  31. maxProfit = prices[i] - minPrice;
  32. }
  33. }
  34. return maxProfit;
  35. }
  36. }

(6) 41.缺失的第一个正数

  1. class Solution {
  2. public int firstMissingPositive(int[] nums) {
  3. for (int i = 0; i<nums.length;i++) {
  4. while (nums[i] >=1 && nums[i]<=nums.length && nums[i] != nums[nums[i] -1]) {
  5. swap(nums, i, nums[i] -1);
  6. }
  7. }
  8. for (int i=0;i<nums.length;i++) {
  9. if (i != nums[i]-1) {
  10. return i+1;
  11. }
  12. }
  13. return nums.length +1;
  14. }
  15. private void swap(int[] nums, int i,int j) {
  16. int temp = nums[i];
  17. nums[i] = nums[j];
  18. nums[j] = temp;
  19. }
  20. }

(7) 46.全排列

  1. public class Permute {
  2. public List<List<Integer>> permute(int[] nums) {
  3. List<List<Integer>> result = new ArrayList<>();
  4. if (nums == null || nums.length == 0) {
  5. return result;
  6. }
  7. List<Integer> outPut = new ArrayList<>();
  8. for (int i=0; i< nums.length; i++) {
  9. outPut.add(nums[i]);
  10. }
  11. backTrack(0, nums.length, outPut, result);
  12. return result;
  13. }
  14. public void backTrack(int first, int n, List<Integer> outPut, List<List<Integer>> result) {
  15. if (first == n) {
  16. result.add(new ArrayList<>(outPut));
  17. }
  18. for (int i = first; i<n; i++) {
  19. Collections.swap(outPut, first, i);
  20. backTrack(first+1, n, outPut, result);
  21. Collections.swap(outPut, first, i);
  22. }
  23. }
  24. }

(8) 1. 两数之和

  1. class Solution {
  2. public int[] twoSum(int[] nums, int target) {
  3. HashMap<Integer, Integer> numAndIndex = new HashMap<>();
  4. for (int i=0;i<nums.length;i++) {
  5. int b = target - nums[i];
  6. if (numAndIndex.containsKey(b)) {
  7. return new int[]{
  8. i, numAndIndex.get(b)};
  9. }
  10. numAndIndex.put(nums[i], i);
  11. }
  12. return new int[0];
  13. }
  14. }

(9) 128. 最长连续序列

  1. public int longestConsecutive(int[] nums) {
  2. HashSet<Integer> numSet = new HashSet<>();
  3. for (int i=0; i<nums.length;i++) {
  4. numSet.add(nums[i]);
  5. }
  6. int maxLength = 0;
  7. for (int i =0;i<nums.length;i++) {
  8. if (!numSet.contains(nums[i] - 1)) {
  9. int currentNum = nums[i];
  10. int currentLength = 1;
  11. while (numSet.contains(currentNum + 1)) {
  12. currentNum +=1;
  13. currentLength ++;
  14. }
  15. maxLength = Math.max(maxLength, currentLength);
  16. }
  17. }
  18. return maxLength;
  19. }

发表评论

表情:
评论列表 (有 0 条评论,292人围观)

还没有评论,来说两句吧...

相关阅读

    相关 算法:位运算

    位运算 程序中的所有数在计算机内存中都是以 0、1 二进制的形式储存的。位运算就是直接对整数在内存中的二进制位进行操作。 计算机对二进制数据进行的运算(+、-

    相关 贪心算法

    1.递增数组 题目链接:[递增数组][Link 1] 题目介绍: > 牛牛有一个数组array,牛牛可以每次选择一个连续的区间,让区间的数都加1,他想知道把这

    相关 算法-

    剑指Offer快速过了一遍 字节-飞书高频题-前15 各公司的高频面试算法题,可在 [CodeTop][]查询 (1) 146. LRU 缓存机制 我的实现

    相关 【自用】算法路径

    知识点总结: 排序算法(堆排序、快排、归并) 动态规划 回溯算法 链表、二叉树、数组、堆、栈 路径: 1. 把总结的题目复习一遍 2. 复习牛