codetop高频(1)
无重复字符的最长子串
时间复杂度O(n),使用滑动窗口遍历,数组存每个字符在窗口里的数量。
class Solution {public int lengthOfLongestSubstring(String s) {int num[]=new int[300];int ans=0;for(int i=0,j=0;i<s.length();i++){num[s.charAt(i)]++;while(j<i&&num[s.charAt(i)]>1){num[s.charAt(j)]--;j++;}ans=Math.max(ans,i-j+1);}return ans;}}
lru缓存机制
利用集合类linkedhashmap来实现,初始化参数设置为true,即为开启lru
注意获取的时候返回的都是key
获取最老元素:cache.keySet().iterator().next();
class LRUCache {private int capacity;private HashMap<Integer,Integer> cache=new LinkedHashMap<>(16,075f,true);public LRUCache(int capacity) {this.capacity=capacity;}public int get(int key) {Integer cur=cache.get(key);return cur==null?-1:cur;}public void put(int key, int value) {if(cache.remove(key)!=null){cache.put(key,value);return ;}if(capacity==cache.size()){Integer oldnode=cache.keySet().iterator().next();cache.remove(oldnode);}cache.put(key,value);}
}/*** Your LRUCache object will be instantiated and called as such:* LRUCache obj = new LRUCache(capacity);* int param_1 = obj.get(key);* obj.put(key,value);*/
带过期时间的lru(拓展)
值存一个类,类里包括value和过期时间,
初始化时简历linkedHashMap并初始化accessorder为true,让它按找访问顺序排序(get\put时更新),这里它会自动将最近访问移到链表最前面,还有重写里面的removeEldestEntry方法,它会在put新元素时检查是否要移除最老元素,如果为true则移除。
这里put方法:封装一下过期时间然后插入Map
get方法:先看看有没有,没有返回null,如果过期了也返回null,有的话返回value。
(其实这个代码有一个小bug,那就是对于未访问但已过期的元素没有及时删除,不过要实现完整的在面试的短时间内感觉够呛,这样感觉应付面试官也够用了)
import java.util.*;
import java.util.concurrent.locks.*;class Expirelrucache<K,V>
{private final int capacity;private final Map<K,Entry<V>>cache;private final Lock lock=new ReentrantLock();static class Entry<V>{V value;long expiration;Entry(V value,long expiration){this.value=value;this.expiration=expiration;}}public Expirelrucache(int capacity){this.capacity=capacity;this.cache=new LinkedHashMap<K, Entry<V>>(capacity,0.75f,true){@Overrideprotected boolean removeEldestEntry(Map.Entry<K,Entry<V>> eldest){return size()>capacity;}};}
public V get(K key)
{lock.lock();try{Entry<V> entry=cache.get(key);if(entry==null) return null;if(System.currentTimeMillis()>entry.expiration){cache.remove(entry);return null;}return entry.value;}finally{lock.unlock();}
}
public void put(K key,V value,int expirationSeconds)
{lock.lock();try{long expiretime= System.currentTimeMillis()+expirationSeconds*1000;cache.put(key,new Entry<>(value,expiretime));}finally{lock.unlock();}
}
}public class Javaacm
{public static void main(String []args){// Scanner scanner = new Scanner(System.in);Expirelrucache<String, Integer> cache = new Expirelrucache<>(2);cache.put("a", 100, 5); cache.put("b", 200, 10); System.out.println("获取a:" + cache.get("a"));System.out.println("获取b:" + cache.get("b")); cache.put("c", 300, 10); System.out.println("添加c,获取a:" + cache.get("a")); }}
反转链表
搞清楚cur(旧链表头结点)和pre(新链表头节点)就行,pre最后指向新的头节点,cur最后指向null
/*** 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) {ListNode cur=head,pre=null;while(cur!=null){ListNode next=cur.next;cur.next=pre;pre=cur;cur=next;}return pre;}
}
数组中第k个最大元素
快速选择(最佳) O(N),基于等比数列求和公式算的
利用了快排分治的思想
class Solution {int num[];public int findKthLargest(int[] nums, int k) {num=nums;return find(0,nums.length-1,nums.length-k);}int find(int l,int r,int k){if(l==r)return num[k];int x=num[(l+r)/2],i=l-1,j=r+1;while(i<j){do i++;while(num[i]<x);do j--;while(num[j]>x);if(i<j) swap(i,j);}if(k<=j)return find(l,j,k);return find(j+1,r,k);}void swap(int a,int b){int t=num[a];num[a]=num[b];num[b]=t;}
}
使用集合 O(Nlogk),最小堆存元素,超过k了就移除堆顶,实现简单
class Solution {public int findKthLargest(int[] nums, int k) {PriorityQueue<Integer> que=new PriorityQueue<>();for(int cur:nums){que.offer(cur);if(que.size()>k)que.poll();}return que.poll();}
}
k个一组反转链表
首先创建一个头结点,然后要利用四指针去修改。
其实四个指针最终要是知道他们的作用,
一个指向反转的前一个,负责连接
两个负责进行反转,反转后变为头节点和,剩余链表头结点
再来一个记录反转后链表的尾结点,只需刚开始记录一下头即可
/*** 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 reverseKGroup(ListNode head, int k) {ListNode hh=new ListNode(0,head);ListNode ll=hh,r=head,cur=head,pre=null;ListNode p=head; int n=0;while(p!=null){p=p.next;n++;}for(int i=n;i>=k;i-=k){for(int j=0;j<k;j++){ListNode next=cur.next;cur.next=pre;pre=cur;cur=next;}ll.next=pre;r.next=cur;ll=r;r=cur;}return hh.next;}
}