1.力扣原题:最长不重复序列
import java.util.*;
public class kuaishou {
public static void main(String[] args){
Scanner in=new Scanner(System.in);
String s=in.nextLine();
System.out.println(longestPalindrome(s));
}
public static String longestPalindrome(String s){
if(s==null ||s.length()==0){
return "";
}
int[] range=new int[2];
char[] str=s.toCharArray();
for(int i=0;i0 &&highrange[1]-range[0]){
range[0]=low;
range[1]=high;
}
return ans;
}
}
2.左边的数比它小,右边的数比它大
import java.util.*;
public class kuaishou {
public static void main(String[] args){
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
sc.nextLine();
int[] array=new int[n];
int index=0;
while(index=0; i--) {
//min=arr[min]>=arr[i]?i:min;
if(arr[min]>=arr[i]){
min=i;
}
if (min == i) {
mos[i]++;
}
}
}
}
用两个栈实现队列:力扣面试题09
class CQueue {
LinkedList stack1;
LinkedList stack2;
public CQueue() {
stack1 = new LinkedList<>();
stack2 = new LinkedList<>();
}
public void appendTail(int value) {
stack1.add(value);
}
public int deleteHead() {
if (stack2.isEmpty()) {
if (stack1.isEmpty()) return -1;
while (!stack1.isEmpty()) {
stack2.add(stack1.pop());
}
return stack2.pop();
} else return stack2.pop();
}
}
出现1的次数:力扣233
import java.util.*;
public class kuaishou {
public static void main(String[] args){
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
System.out.println(count(n));
}
public static int count(int n){
int base = 1;
int count = 0;
int weight = 0;
int round = 0;
int temp = n;
while(temp>0){
weight = temp%10;
round = temp/10;
temp = round;
count += round*base;
if(weight>1){
count += base;
}else if(weight == 1){
count += n%base+1;
}
base = base*10;
}
return count;
}
}
力扣1302:最深叶子结点的和
class Solution {
public int deepestLeavesSum(TreeNode root) {
if (root == null) return 0;
int num = 0;
Queue queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()) {
num = 0;
int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();
num += node.val;
if (node.left != null) queue.offer(node.left);
if (node.right != null) queue.offer(node.right);
}
}
return num;
}
}
剑指offer:全排列
import java.util.ArrayList;
import java.util.Collections;
public class Solution {
public ArrayList Permutation(String str) {
//dp
ArrayList res=new ArrayList();
if(str.length()==0||str==null)return res;
int n= str.length();
helper(res,0,str.toCharArray());
Collections.sort(res);
return res;
}
public void helper( ArrayList res,int index,char []s)
{
if(index==s.length-1)res.add(new String(s));
for(int i=index;i
先序遍历:力扣144
递归
public List preorderTraversal(TreeNode root) {
List res = new ArrayList<>();
preorder(root, res);
return res;
}
private void preorder(TreeNode root, List res){
if(root != null){
res.add(root.val);
preorder(root.left, res);
preorder(root.right, res);
}
}
迭代
public List preorderTraversal(TreeNode root) {
List res = new ArrayList();
if (root == null) {
return res;
}
Stack stack = new Stack();
stack.push(root);
while (!stack.isEmpty()) {
TreeNode node = stack.pop();
res.add(Integer.valueOf(node.val));
if (node.right != null) {
stack.push(node.right);
}
if (node.left != null) {
stack.push(node.left);
}
}
return res;
}
安全自增1
public class Count {
private static int counter = 0 ;
public static int getCount(){
// 线程安全,不会锁住整个Count对象
synchronized(Count.class){
return counter++;
}
}
}
双重检验的单例模式
public class Singleton {
private volatile static Singleton instance = null;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {// 1
if (instance == null) {// 2
instance = new Singleton();// 3
}
}
}
return instance;
}
}
解释为什么要两次判空
内部:为了防止生成多个实例
外部:提高性能,减少执行次数,防止加不必要的锁
树的层次遍历
public List> levelOrder(TreeNode root) {
if(root == null)
return new ArrayList<>();
List> res = new ArrayList<>();
Queue queue = new LinkedList();
queue.add(root);
while(!queue.isEmpty()){
int count = queue.size();
List list = new ArrayList();
while(count > 0){
TreeNode node = queue.poll();
list.add(node.val);
if(node.left != null)
queue.add(node.left);
if(node.right != null)
queue.add(node.right);
count--;
}
res.add(list);
}
return res;
}
力扣:栈的最小值
class MinStack {
private Stack- stack=new Stack<>();
private int min=Integer.MAX_VALUE;
static class Item{
//元素当前的值
private int val;
//元素及元素下最小的值
private int curMin;
}
public MinStack() {
}
public void push(int x) {
Item item=new Item();
item.val=x;
if(x
手写快排
import java.util.*;
public class QuickSort {
public static void main(String[] args) {
QuickSort quickSort=new QuickSort();
int[] arrays={2,5,3,4,6,1};
quickSort.quickSort(arrays,0,arrays.length-1);
}
public int partition(int[] arrays, int left, int right) {
int pivat = arrays[left];
System.out.println("挖第一个数这个坑\t" + pivat);
while(left < right) {
// 从右往左找比pivat小的数,没找到则跳过
while(left < right && arrays[right] >= pivat) {
System.out.println("大,看看我左边");
right--;
}
// 找到了就把右边的数放到左边去
if(left < right) {
System.out.println("小,移位");
arrays[left] = arrays[right];
System.out.println("现在状态\t" + Arrays.toString(arrays));
left++;
}
// 从左往右找比pivat大的数,没找到则跳过
while(left < right && arrays[left] < pivat) {
System.out.println("小,看看我右边");
left++;
}
// 找到的了就把左边的数放到右边去
if(left < right) {
System.out.println("大,移位");
arrays[right] = arrays[left];
System.out.println("现在状态\t" + Arrays.toString(arrays));
right--;
}
}
// 最后剩下的坑位放pivat
arrays[left] = pivat;
System.err.println("完成\t" + Arrays.toString(arrays));
return left;
}
public void quickSort(int[] arrays, int left, int right) {
if(left < right) {
int index = this.partition(arrays, left, right);
quickSort(arrays, left, index - 1);
quickSort(arrays, index + 1, right);
}
}
}
力扣:合并一个有序链表
class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
// 类似归并排序中的合并过程
ListNode dummyHead = new ListNode(0);
ListNode cur = dummyHead;
while (l1 != null && l2 != null) {
if (l1.val < l2.val) {
cur.next = l1;
cur = cur.next;
l1 = l1.next;
} else {
cur.next = l2;
cur = cur.next;
l2 = l2.next;
}
}
// 任一为空,直接连接另一条链表
if (l1 == null) {
cur.next = l2;
} else {
cur.next = l1;
}
return dummyHead.next;
}
奇数移到偶数前
class Solution {
public int[] exchange(int[] 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;
}
}
return nums;
}
}
力扣:最大数
class Solution {
/**
* @param nums 一组非负整数
* @return - String.compareTo() 是按照 lexicographically, 字典顺序排列的
* - 利用compareTo, 来倒序排列 string, 刚好就得到我们要的结果.
*/
public String largestNumber(int[] nums) {
//合法性
if (nums == null || nums.length == 0) {
return "";
}
//数字数组->字符数组 转化
String[] strArr = new String[nums.length];
for (int i = 0; i < strArr.length; i++) {
strArr[i] = String.valueOf(nums[i]);
}
//重写排序规则 12-14ms
// Arrays.sort(strArr, new Comparator() {
// @Override
// public int compare(String o1, String o2) {
// //继承此方法的时候,要自定义比较器,conpareTo方法返回值为1(升序),0,-1(降序)。
// //返回正值 交换;负值不交换
// return (o2 + o1).compareTo((o1 + o2));
// }
// });
//Lambda表达式 重写排序规则 速度慢了5倍 72-82ms
Arrays.sort(strArr, (o1, o2) -> (o2 + o1).compareTo(o1 + o2));
//字符数组->字符串 转化
StringBuilder sb = new StringBuilder();
for (String aStrArr : strArr) {
sb.append(aStrArr);
}
String result = sb.toString();
//特殊情况 若干个零
if (result.charAt(0) == '0') {
result = "0";
}
return result;
}
}
力扣:匹配的括号
class Solution {
public List generateParenthesis(int n) {
List res = new ArrayList<>();
backTrack(new StringBuilder(), res, n, n);
return res;
}
private void backTrack(StringBuilder tmp, List res, int l, int r) {
if (l == 0 && r == 0) {
res.add(tmp.toString());
return;
}
if (r < l)
return;
if (l != 0)
backTrack(tmp.append("("), res, l - 1, r);
if (r != 0)
backTrack(new StringBuilder(tmp).append(")"), res, 1, r - 1);
}
}
手写一个阻塞队列
public class ZerahBlockQueue {
//队列容器
private List container = new ArrayList<>();
private Lock lock = new ReentrantLock();
//Condition
// 队列为空
private Condition isNull = lock.newCondition();
// 队列已满
private Condition isFull = lock.newCondition();
private volatile int size;
private volatile int capacity;
ZerahBlockQueue(int cap) {
this.capacity = cap;
}
public void add(int data) {
try {
lock.lock();
try {
while (size >= capacity) {
System.out.println("队列已满,释放锁,等待消费者消费数据");
isFull.await();
}
} catch (InterruptedException e) {
isFull.signal();
e.printStackTrace();
}
++size;
container.add(data);
isNull.signal();
} finally {
lock.unlock();
}
}
public int take(){
try {
lock.lock();
try {
while (size == 0){
System.out.println("阻塞队列空了,释放锁,等待生产者生产数据");
isNull.await();
}
}catch (InterruptedException e){
isFull.signal();
e.printStackTrace();
}
--size;
int res = container.get(0);
container.remove(0);
isFull.signal();
return res ;
}finally {
lock.unlock();
}
}
}
测试阻塞队列
public class MyBlockQueueTest {
public static void main(String[] args) {
ZerahBlockQueue queue = new ZerahBlockQueue(5);
Thread thread1 = new Thread(() -> {
for (int i = 0; i < 100; i++) {
queue.add(i);
System.out.println("拉个:" + i);
try {
Thread.sleep(500);
}catch (InterruptedException e){
e.printStackTrace();
}
}
});
Thread thread2 = new Thread(() -> {
for(;;){
System.out.println("屎壳郎开始工作,消费:" + queue.take());
try {
Thread.sleep(800);
}catch (InterruptedException e){
e.printStackTrace();
}
}
});
thread1.start();
thread2.start();
}
}
搜索旋转数组
class Solution {
public int search(int[] nums, int target) {
if(nums == null || nums.length == 0) return -1;
int left = 0, right = nums.length - 1;
while(left + 1 < right) {
int mid = (left + right) >>> 1;
if(nums[left] < nums[mid]) {
if(nums[left] <= target && target <= nums[mid]) {
right = mid;
} else {
left = mid;
}
} else if(nums[mid] < nums[left]) {
if(target >= nums[mid] && target <= nums[right]) {
left = mid;
} else {
right = mid;
}
} else left++;
}
if(nums[left] == target) return left;
if(nums[right] == target) return right;
return -1;
}
}
链表逆序
public ListNode reverseList(ListNode head) {
ListNode pre = null;
ListNode cur = head;
while(cur!=null) {
ListNode next = cur.next;
cur.next = pre;
pre = cur;
cur = next;
}
return pre;
}
力扣:k链表的反转
class Solution {
public ListNode reverseKGroup(ListNode head, int k) {
ListNode prev = null;
ListNode cur = head;
ListNode next = null;
ListNode check = head;
int canProceed = 0;
int count = 0;
// 检查链表长度是否满足翻转
while (canProceed < k && check != null) {
check = check.next;
canProceed++;
}
// 满足条件,进行翻转
if (canProceed == k) {
while (count < k && cur != null) {
next = cur.next;
cur.next = prev;
prev = cur;
cur = next;
count++;
}
if (next != null) {
// head 为链表翻转后的尾节点
head.next = reverseKGroup(next, k);
}
// prev 为链表翻转后的头结点
return prev;
} else {
// 不满住翻转条件,直接返回 head 即可
return head;
}
}
}
只出现一次的次数
class Solution {
public int[] singleNumbers(int[] nums) {
int sum=0;
//得到异或结果,即为不相同两个数的异或结果sum
for(int num:nums)
sum^=num;
//得到sum的二进制的1的最低位
int flag=(-sum)∑
int result[]=new int[2];
//分成两个组进行异或,每组异或后的结果就是不相同两个数的其中之一
for(int num:nums){
if((flag&num)==0)
result[0]^=num;
else{
result[1]^=num;
}
}
return result;
}
}
判断链表有没有环
public class Solution {
public boolean hasCycle(ListNode head) {
if(head == null || head.next == null) return false;
ListNode fast = head.next;
ListNode slow = head;
while(fast != slow){
if(fast.next == null || fast.next.next == null) return false;
fast = fast.next.next;
slow = slow.next;
}
return true;
}
}
树转链表,力扣114
class Solution {
public void flatten(TreeNode root) {
if(root == null) return;
flatten(root.left);
flatten(root.right);
TreeNode tmp = root.right;
root.right = root.left;
root.left = null;
while(root.right != null) root = root.right;
root.right = tmp;
}
}
最小回文数
void lagerSmallestPlalindrome(int n)
{
if (n < 0)
{
cout<<'0'<= 0;--i)
{
cout<= 0; --i)
{
cout<= 0;--i)
{
cout<= 0;--i)
{
cout<= 0;--i)
{
cout<= 0;--i)
{
cout<