IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> LeetCode 抽空一练 7.1 -> 正文阅读

[数据结构与算法]LeetCode 抽空一练 7.1

206. 反转链表

给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。

package com.jiawei.WeekOne;

import com.jiawei.Utils.ListNode;

public class ReverseList {
  public ListNode reverseList(ListNode head) {
    ListNode prev = null;
    ListNode curr = head;
    while (curr != null) {
      ListNode next = curr.next;
      curr.next = prev;
      prev = curr;
      curr = next;
    }
    return prev;
  }
}

吐槽一句,至今觉得用java写链表这件事十分阴间,底层基本实现的功能还要为了手写而手写,很难受

146. LRU 缓存

请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。
实现 LRUCache 类:
LRUCache(int capacity) 以 正整数 作为容量 capacity 初始化 LRU 缓存
int get(int key) 如果关键字 key 存在于缓存中,则返回关键字的值,否则返回 -1 。
void put(int key, int value) 如果关键字 key 已经存在,则变更其数据值 value ;如果不存在,则向缓存中插入该组 key-value 。如果插入操作导致关键字数量超过 capacity ,则应该 逐出 最久未使用的关键字。
函数 get 和 put 必须以 O(1) 的平均时间复杂度运行。

// 以下代码是借鉴的b17a大佬的,我自己拿着第一反应就是直接继承LinkedHashMap,但是面试肯定不能这么写,所以学大佬重写了底层
package com.jiawei.WeekOne;

import java.util.HashMap;
import java.util.Map;

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;
  }
}

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

给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。

//没啥好说的,HashSet来做,类似的移动窗口都可以写
package com.jiawei.WeekOne;

import java.util.HashSet;
import java.util.Set;

public class LengthOfLongestSubstring {
  public static int lengthOfLongestSubstring(String s) {
    Set<Character> occ = new HashSet<Character>();
    int n = s.length();
    int rk = -1, ans = 0;
    for (int i = 0; i < n; ++i) {
      if (i != 0) {
        occ.remove(s.charAt(i - 1));
      }
      while (rk + 1 < n && !occ.contains(s.charAt(rk + 1))) {
        occ.add(s.charAt(rk + 1));
        ++rk;
      }
      ans = Math.max(ans, rk - i + 1);
    }
    return ans;
  }

  public static void main(String[] args) {
    String s = "abcabcbb";
    System.out.println("最长无重复字串长度为:" + lengthOfLongestSubstring(s));
  }
}

215. 数组中的第K个最大元素

给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。

请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。

// 我的评价是,谁用sort函数谁就能承包面试官今日份笑点,人面试官又不傻,来你这看你调包呢
// 两个函数,冒泡不需要建树之类的操作,偷懒专用,但是时间复杂度相对高,堆排序是标答
package com.jiawei.WeekOne;

class FindKthLargest {
  public static int findKthLargest(int[] nums, int k) {
    int tmp;
    for (int i = 0; i < k; i++) {
      for (int j = 0; j < nums.length - i - 1; j++) {
        if (nums[j] > nums[j + 1]) {
          tmp = nums[j];
          nums[j] = nums[j + 1];
          nums[j + 1] = tmp;
        }
      }
    }
    return nums[nums.length - k];
  }

  public static int findKthLargestHeap(int[] nums, int k) {
    int heapSize = nums.length;
    buildMaxHeap(nums, heapSize);
    // 建堆完毕后,nums【0】为最大元素。逐个删除堆顶元素,直到删除了k-1个。
    for (int i = nums.length - 1; i >= nums.length - k + 1; --i) {
      // 先将堆的最后一个元素与堆顶元素交换,由于此时堆的性质被破坏,需对此时的根节点进行向下调整操作。
      swap(nums, 0, i);
      // 相当于删除堆顶元素,此时长度变为nums.length-2。即下次循环的i
      --heapSize;
      maxHeapify(nums, 0, heapSize);
    }
    return nums[0];
  }

  public static void buildMaxHeap(int[] a, int heapSize) {
    // 从最后一个父节点位置开始调整每一个节点的子树。数组长度为heasize,因此最后一个节点的位置为heapsize-1,所以父节点的位置为heapsize-1-1/2。
    for (int i = (heapSize - 2) / 2; i >= 0; --i) {
      maxHeapify(a, i, heapSize);
    }
  }

  public static void maxHeapify(int[] a, int i, int heapSize) { // 调整当前结点和子节点的顺序。
    // left和right表示当前父节点i的两个左右子节点。
    int left = i * 2 + 1, right = i * 2 + 2, largest = i;
    // 如果左子点在数组内,且比当前父节点大,则将最大值的指针指向左子点。
    if (left < heapSize && a[left] > a[largest]) {
      largest = left;
    }
    // 如果右子点在数组内,且比当前父节点大,则将最大值的指针指向右子点。
    if (right < heapSize && a[right] > a[largest]) {
      largest = right;
    }
    // 如果最大值的指针不是父节点,则交换父节点和当前最大值指针指向的子节点。
    if (largest != i) {
      swap(a, i, largest);
      // 由于交换了父节点和子节点,因此可能对子节点的子树造成影响,所以对子节点的子树进行调整。
      maxHeapify(a, largest, heapSize);
    }
  }

  public static void swap(int[] a, int i, int j) {
    int temp = a[i];
    a[i] = a[j];
    a[j] = temp;
  }

  public static void main(String[] args) {
    int nums[] = {3, 2, 1, 5, 6, 4};
    System.out.println(findKthLargestHeap(nums, 4));
  }
}

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/lru-cache
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-07-05 23:40:24  更:2022-07-05 23:41:56 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/18 5:58:20-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码