快手面试算法题合集

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<

 

你可能感兴趣的:(快手面试算法题合集)