算法-刷题

剑指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;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值