文章目录
leetcode-25. K 个一组翻转链表
给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。
class Solution {
public ListNode reverseKGroup(ListNode head, int k) {
if(head==null) return null;
ListNode dummy = new ListNode(0);
dummy.next = head;
ListNode pre = dummy;
ListNode end = dummy;
while (end.next!=null){
for(int i=0;i<k && end!=null;i++){
end = end.next;
}
if(end==null){
break;
}
ListNode start = pre.next;
ListNode next = end.next;
end.next = null;
pre.next = reverse(start);
start.next = next;
end = start;
pre = end;
}
return dummy.next;
}
private ListNode reverse(ListNode start) {
if(start==null) return null;
ListNode pre = null;
ListNode cur = start;
while (cur!=null){
ListNode tmp = cur.next;
cur.next = pre;
pre = cur;
cur = tmp;
}
return pre;
}
}
leetcode-146. LRU 缓存机制
运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制 。
实现 LRUCache 类:
LRUCache(int capacity) 以正整数作为容量 capacity 初始化 LRU 缓存
int get(int key) 如果关键字 key 存在于缓存中,则返回关键字的值,否则返回 -1 。
void put(int key, int value) 如果关键字已经存在,则变更其数据值;如果关键字不存在,则插入该组「关键字-值」。当缓存容量达到上限时,它应该在写入新数据之前删除最久未使用的数据值,从而为新的数据值留出空间。
class DoubleLinkListNode{
int key;
int value;
DoubleLinkListNode pre;
DoubleLinkListNode next;
public DoubleLinkListNode(){}
public DoubleLinkListNode(int key,int value){
this.key = key;
this.value = value;
}
}
class LRUCache {
//缓存
HashMap<Integer,DoubleLinkListNode> cache = new HashMap<>();
//缓存的大小
private int size;
//缓存的容量
private int capacity;
//双向链表的虚拟头部和尾部
private DoubleLinkListNode head;
private DoubleLinkListNode tail;
//构造函数对数据初始化
public LRUCache(int capacity) {
this.capacity = capacity;
head = new DoubleLinkListNode();
tail = new DoubleLinkListNode();
head.next = tail;
tail.pre = head;
}
public int get(int key) {
DoubleLinkListNode node = cache.get(key);
if(node==null){
return -1;
}else{
//将key对应的节点移动到双向链表的头部:1、将当前节点node删除 2、将该节点添加到链表头部
//将node节点删除
node.pre.next = node.next;
node.next.pre = node.pre;
//将该节点添加到链表头部
node.pre = head;
node.next = head.next;
head.next.pre = node;
head.next = node;
return node.value;
}
}
public void put(int key, int value) {
DoubleLinkListNode node = cache.get(key);
if(node==null){
//构建当前节点加入缓存中
DoubleLinkListNode newNode = new DoubleLinkListNode(key,value);
cache.put(key,newNode);
//将newNode这个节点添加到双向链表的头部
newNode.pre = head;
newNode.next = head.next;
head.next.pre = newNode;
head.next = newNode;
//缓存的大小加1
size++;
//如果size超出容量,就将缓存中最先加入的数据删除
if(size>capacity){
//1、删除双向链表的尾部节点,同时返回该节点
//获取尾部节点
DoubleLinkListNode node1 = tail.pre;
//删除该节点
node1.pre.next = node1.next;
node1.next.pre = node1.pre;
//2、删除缓存中该节点的对应项
cache.remove(node1.key);
size--;
}
}else{
// 如果node存在,修改value,改为最新值
node.value = value;
// 将这个节点移动到链表的头部
// 先删除该节点
node.pre.next = node.next;
node.next.pre = node.pre;
// 然后将该节点添加到链表的头部
node.pre = head;
node.next = head.next;
head.next.pre = node;
head.next = node;
}
}
}
leetcode - 15. 三数之和
给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有满足条件且不重复的三元组。
方法:双指针
class Solution {
List<List<Integer>> res = new ArrayList<>();
public List<List<Integer>> threeSum(int[] nums) {
if(nums.length==0) return res;
Arrays.sort(nums);
for(int i=0;i<nums.length;i++){
if(i>0 && nums[i]==nums[i-1]) continue;
int left = i+1;
int right = nums.length-1;
while (left<right){
int sum = nums[left]+nums[right]+nums[i];
if(sum==0){
res.add(Arrays.asList(nums[left],nums[right],nums[i]));
while (left<right && nums[left]==nums[left+1]) left++;
while (left<right && nums[right]==nums[right-1]) right--;
left++;
right--;
}else if(sum<0){
left++;
}else{
right--;
}
}
}
return res;
}
}
leetcode - 1. 两数之和
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。
方法:哈希表
class Solution {
public int[] twoSum(int[] nums, int target) {
if(nums.length==0) return new int[0];
HashMap<Integer,Integer> map = new HashMap<>();
for(int i=0;i<nums.length;i++){
if(map.containsKey(target-nums[i])){
return new int[]{i,map.get(target-nums[i])};
}
map.put(nums[i],i);
}
return new int[]{-1,-1};
}
}
微博面试题:
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 3个 整数,并返回他们的数组下标。你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。
class Solution {
public int[] threeSum(int[] nums, int target) {
if(nums.length==0) return new int[0];
HashMap<Integer,Integer> map = new HashMap<>();
for(int i=0;i<nums.length;i++){
for(int j=i+1;j<nums.length;j++){
if(map.containsKey(target-nums[i]-nums[j])){
return new int[]{i,j,map.get(target-nums[i]-nums[j])};
}
map.put(nums[i],i);
}
}
return new int[]{-1,-1,-1};
}
}
leetcode - 102. 二叉树的层序遍历
给你一个二叉树,请你返回其按 层序遍历 得到的节点值。 (即逐层地,从左到右访问所有节点)。
class Solution {
List<List<Integer>> res = new ArrayList<>();
public List<List<Integer>> levelOrder(TreeNode root) {
if(root==null) return res;
LinkedList<TreeNode> queue = new LinkedList<>();
queue.add(root);
while (!queue.isEmpty()){
ArrayList<Integer> list = new ArrayList<>();
int len = queue.size();
for(int i=0;i<len;i++){
TreeNode node = queue.poll();
list.add(node.val);
if(node.left!=null) queue.add(node.left);
if(node.right!=null) queue.add(node.right);
}
res.add(list);
}
return res;
}
}
leetcode - 94. 二叉树的中序遍历
给定一个二叉树的根节点 root
,返回它的 中序 遍历。
方法:迭代
class Solution {
List<Integer> res = new ArrayList<>();
public List<Integer> inorderTraversal(TreeNode root) {
if(root==null) return res;
Stack<TreeNode> stack = new Stack<>();
stack.add(root);
while (!stack.isEmpty()){
TreeNode node = stack.pop();
if(node!=null){
if(node.right!=null) stack.push(node.right);
stack.push(node);
stack.push(null);
if(node.left!=null) stack.push(node.left);
}else{
res.add(stack.pop().val);
}
}
return res;
}
}
方法:递归
class Solution {
List<Integer> res = new ArrayList<>();
public List<Integer> inorderTraversal(TreeNode root) {
if(root==null) return res;
dfs(root);
return res;
}
private void dfs(TreeNode root) {
if(root==null) return;
dfs(root.left);
res.add(root.val);
dfs(root.right);
}
}
leetcode - 141. 环形链表
给定一个链表,判断链表中是否有环。如果链表中存在环,则返回 true 。 否则,返回 false 。
public class Solution {
public boolean hasCycle(ListNode head) {
if(head==null) return false;
ListNode fast = head;
ListNode slow = head;
while (true){
if(fast==null || fast.next==null) return false;
fast = fast.next.next;
slow = slow.next;
if(fast==slow) return true;
}
}
}
leetcode - 142. 环形链表 II
给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。说明:不允许修改给定的链表。
public class Solution {
public ListNode detectCycle(ListNode head) {
if(head==null) return null;
ListNode fast = head;
ListNode slow = head;
while (true){
if(fast==null || fast.next==null) return null;
fast = fast.next.next;
slow = slow.next;
if(fast==slow) break;
}
slow = head;
while (slow!=fast){
slow = slow.next;
fast = fast.next;
}
return slow;
}
}