非力扣100原题
多线程交替打印0-100
2个线程交替打印0-100
public class Main {private static final Object LOCK = new Object();private static volatile int count = 0;private static final int MAX = 100;public static void main(String[] args) {Thread thread = new Thread(new Seq(0));Thread thread1 = new Thread(new Seq(1));thread.start();thread1.start();}static class Seq implements Runnable {private final int index;public Seq(int index) {this.index = index;}@Overridepublic void run() {// Run方法只要执行结束了,线程就结束了while (count < MAX) {// 同步代码块,一个时刻只能有一个线程获取到锁synchronized (LOCK) {// 获取到锁就进来判断,当前是否轮到该线程打印while (count % 2 != index) {// 不是当前线程打印,那么就让当前线程去wait,它会自动释放锁,所以其他线程可以进来try {LOCK.wait();// 当线程被唤醒时,会尝试重新进入synchronized代码块} catch (Exception e) {e.printStackTrace();}}// 是当前线程打印, 但count>MAXif (count > MAX) {LOCK.notifyAll();return;}System.out.println("Thread-" + index + ":" + count);count++;LOCK.notifyAll();}}}}
}
public class Main {private static final Object LOCK = new Object();private static volatile int count = 0;private static final int MAX = 100;public static void main(String[] args) {Thread thread = new Thread(new Seq(0));Thread thread1 = new Thread(new Seq(1));Thread thread2 = new Thread(new Seq(2));thread.start();thread1.start();thread2.start();}static class Seq implements Runnable {private final int index;public Seq(int index) {this.index = index;}@Overridepublic void run() {// Run方法只要执行结束了,线程就结束了while (count < MAX) {// 同步代码块,一个时刻只能有一个线程获取到锁synchronized (LOCK) {// 获取到锁就进来判断,当前是否轮到该线程打印while (count % 3 != index) {// 不是当前线程打印,那么就让当前线程去wait,它会自动释放锁,所以其他线程可以进来try {LOCK.wait();// 当线程被唤醒时,会尝试重新进入synchronized代码块} catch (Exception e) {e.printStackTrace();}}// 是当前线程打印, 但count>MAXif (count > MAX) {LOCK.notifyAll();return;}System.out.println("Thread-" + index + ":" + count);count++;LOCK.notifyAll();}}}}
}
多线程交替打印ABC
import java.util.concurrent.Semaphore;
// 多线程打印ABC
public class Printer {private final Semaphore semA = new Semaphore(1); // 信号量A设置为1,从A开始打印private final Semaphore semB = new Semaphore(0);private final Semaphore semC = new Semaphore(0);private static int n = 3; // 打印轮次public static void main(String[] args) {Printer printer = new Printer();new Thread(()->printer.print('A',printer.semA,printer.semB)).start();new Thread(()->printer.print('B',printer.semB,printer.semC)).start();new Thread(()->printer.print('C',printer.semC,printer.semA)).start();}public void print(char ch, Semaphore current, Semaphore next) {try {for (int i = 0; i < n; i++) {current.acquire(); // 获取当前信号量System.out.println(Thread.currentThread().getName() + ": " + ch);next.release(); // 释放下一个信号量}} catch (InterruptedException e) {e.printStackTrace();}}
}
奇偶交换
给定数组,奇数在前,偶数在后
import java.util.Arrays;
public class Solution {public static int[] jiaohuang(int[] nums){if(nums.length<2||nums == null){return nums;}int left = 0;int right = nums.length-1;while (left<right){// 选定偶数while (left<right && nums[left] % 2 !=0){left++;}// 选定奇数while (left<right && nums[right]%2 == 0){right--;}if(left < right){int temp = nums[left];nums[left] = nums[right];nums[right] = temp;left++;right--;}}return nums;}public static void main(String[] args){Solution solution = new Solution();int[] nums = {1,2,3,4};int[] result = solution.jiaohuang(nums);System.out.print(Arrays.toString(nums));}
}
字典序的第k小数字
// 字典序:数字的前缀进行排序,如10<9,因为10的前缀是1<9 // 数组{1,2,-,9,10,11,12}-->{1,10,11,12,2,--,9} // 思路:当前指针+前缀数(非指针概念),当成一个(key,value)形式,cur为key,value = 前缀数 // 如果当前指针<目标指针,while循环, // 计算当前数的节点数(如1-201,那么在1和2之间隔着10-19,100-199:节点数为1+10+10*10) // 如果 当前指针 + 当前前缀节点 <=k,即不在k的范围内,那么当前指针(下个前缀节点) = 当前指针 + 当前前缀节点,前缀数++ // else,在k的范围内,那么当前指针 = cur指针+1,前缀数*10更加细分 //(其实这里有点无限迭代的意思,判断在10-19区间还是继续细分在100-109~190-199区间,但n是固定的,有限迭代)
public int findKthNumber(int n, int k) {long cur = 1; // 当前指针对应long prix = 1; // 当前前缀数,可以把当成一个(key,value)形式,cur为key,value = 前缀数while (cur < k){long prixNum = getCount(prix,n);// 当前前缀节点数量// k不在当前前缀数if(cur+prixNum <= k){cur+=prixNum; // 下个指针 = 当前指针+节点数prix++; // 前缀数++}else {cur++; // 在当前前缀循环,从1变成10,指针从索引0(1)到索引1(10)prix*=10; // 前缀细分}}return (int)prix;}// 当前前缀下的所有子节点数总和=下一个前缀的起点-当前前缀的起点public long getCount(long prix,long n){long count = 0;// 节点数量long prixNext = prix+1; // 下一个前缀数while (prix <= n){count += Math.min(n-1,prixNext)-prix;prix*=10;prixNext*=10;}return count;}
带TTL的LRU缓存
相对于LRU:有一个时间字段ttl,需要改变的是put方法,仅在node不为空时,覆盖时间值,记得加上系统当前时间;在getNode方法中判断,当前节点是否过期,过期则移除节点以及对应的map的key,并返还为空
public class Solution {static class Node{int key,value;long expireTime;// 预定过期时间Node prev,next;Node(int key,int value,long ttl){this.key = key;this.value = value;this.expireTime = System.currentTimeMillis() + ttl;}}static class LRUCacheTTL{private final int capacity;private final Node dummy = new Node(-1,-1,0);private final Map<Integer,Node> map = new HashMap<>();LRUCacheTTL(int capacity) {this.capacity = capacity;dummy.prev = dummy;dummy.next = dummy;}public int get(int key){Node node = getNode(key);if(node == null){return -1;}return node.value;}public void put(int key,int value,long ttl){Node node = getNode(key);if(node != null){node.value = value;node.expireTime = System.currentTimeMillis()+ttl;}node = new Node(key,value,ttl);map.put(key,node);pushFront(node);if(map.size()>capacity){Node backNode = dummy.prev;remove(backNode);map.remove(backNode.key);}}public Node getNode(int key){Node node = map.get(key); // key不存在,返还为nullif(node == null){return null;}if(node.expireTime <= System.currentTimeMillis()){remove(node);map.remove(key);return null;}remove(node);pushFront(node);return node;}public void remove(Node node){node.next.prev = node.prev;node.prev.next = node.next;}public void pushFront(Node node){node.prev = dummy;node.next = dummy.next;dummy.next = node;node.next.prev = node;}}public static void main(String[] args) {LRUCacheTTL cache = new LRUCacheTTL(2);cache.put(1, 1, 3000); // TTL: 3秒cache.put(2, 2, 5000); // TTL: 5秒System.out.println("get(1): " + cache.get(1)); // 1try {Thread.sleep(2000); // 等待2秒} catch (InterruptedException e) {Thread.currentThread().interrupt();}System.out.println("get(2): " + cache.get(2)); // 2try {Thread.sleep(3000); // 再等3秒 → key=1 已过期} catch (InterruptedException e) {Thread.currentThread().interrupt();}System.out.println("get(1): " + cache.get(1)); // -1 (已过期)cache.put(3, 3, 1000); // 触发淘汰,key=2 应该被踢掉System.out.println("get(2): " + cache.get(2)); // -1System.out.println("get(3): " + cache.get(3)); // 3}
}