Java算法面试题

数组

加一

class Solution {
    public int[] plusOne(int[] digits) {
        int len = digits.length;
        int carry = 1; // 进位1
        for (int i=len-1;i>=0;i--){
            int digit = digits[i] + carry;
            digits[i] = digit % 10;
            carry = digit / 10;
        }
        if(carry == 1){
            // [9,9,9]的情况
            digits = new int[len+1];
            digits[0] = 1;
        }
        return digits;
    }
}

两数相加

/**
 * 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 addTwoNumbers(ListNode l1, ListNode l2) {
        ListNode head=null, tail=null;
        int carry = 0;
        while(l1!=null || l2!=null){
            int sum = carry;
            if(l1!=null){
                sum += l1.val;
                l1 = l1.next;
            }
            if(l2!=null){
                sum += l2.val;
                l2 = l2.next;
            }
            if(head==null){
                head = tail = new ListNode(sum%10);
            }else{
                tail.next = new ListNode(sum%10);
                tail = tail.next;
            }
            carry = sum / 10;
        }
        if (carry > 0){
            tail.next = new ListNode(carry);
        }
        return head;
    }
}

相交链表

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    /**
    用双指针pA 、pB循环俩个链表,链表A循环结束就循环链表B,链表A循环结束就循环链表B,
    当pA == pB时就是交点,因为两个指针移动的步数一样
     */
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        // 双链表法
        if (headA==null || headB==null){
            return null;
        }
        ListNode node1 = headA, node2 = headB;
        while(node1 != node2){
            node1 = node1 == null ? headB : node1.next;
            node2 = node2 == null ? headA : node2.next;
        }
        return node1;
    }
}

环形链表

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public boolean hasCycle(ListNode head) {
        // 使用双指针,如果存在环,则快指针一定会追上慢指针
        ListNode fast = head;  
        ListNode slow = head;
        while(fast != null && fast.next != null){
            fast = fast.next.next;
            slow = slow.next;
            if(fast == slow) {
                return true;
            }
        }
        return false;
    }
}

环形链表II

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    // 使用双指针解法
    public ListNode detectCycle(ListNode head) {
        ListNode fast = head, slow = head;
        // 快指针移动两位,慢指针移动一位,相遇说明有环
        while(true){
            if ( fast==null || fast.next == null){
                return null;
            }
            fast = fast.next.next;
            slow = slow.next;
            if(fast == slow){
                break;
            }
        }
        fast = head;
        while(fast != slow){
            fast = fast.next;
            slow = slow.next;
        }
        return fast;
    }
}

链表中倒数第k个节点

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode getKthFromEnd(ListNode head, int k) {
        ListNode fast = head, slow = head;
        for(int i=0;i<k;i++){
            fast = fast.next;
        }
        while(fast != null){
            fast = fast.next;
            slow = slow.next;
        }
        return slow;
    }
}

对链表进行插入排序

/**
 * 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 insertionSortList(ListNode head) {
        if(head==null && head.next == null){
            return null;
        }
        ListNode dummyHead = new ListNode(-1);
        dummyHead.next = head;
        ListNode lastSorted = head;  // 记录最后一个排好序的节点位置
        ListNode cur = head.next;  // 当前要排序的节点

        while(cur != null){
            if(lastSorted.val <= cur.val){ // 当前元素大于前面已排好序的元素值
                lastSorted = lastSorted.next;
            }else{
                ListNode pre = dummyHead;
                // 寻找插入节点位置
                while(pre.next.val <= cur.val){
                    pre = pre.next;
                }
                // 链表节点交换
                lastSorted.next = cur.next;
                cur.next = pre.next;
                pre.next = cur;
            }
            // 调整位置
            cur = lastSorted.next;
        }
        return dummyHead.next;
    }
}

链表排序

/**
 * 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 sortList(ListNode head) {
        if(head == null || head.next == null){
            return head;
        }
        // 快慢指针移动,寻找中间指针
        ListNode slow = head, fast = head;
        while(fast.next != null && fast.next.next != null){
            fast = fast.next.next;
            slow = slow.next;
        }
        // 找到中间节点
        ListNode mid = slow.next;
        // 切断链表
        slow.next = null;
        // 排序左子链表
        ListNode left = sortList(head);
        // 排序右子链表
        ListNode right = sortList(mid);

        // 合并链表
        return merge(left, right);
    }
    public ListNode merge(ListNode left, ListNode right){
        ListNode head = new ListNode(0);
        ListNode temp = head;
        while(left != null && right != null){
            if(left.val <= right.val){
                temp.next = left;
                left = left.next;
            }else{
                temp.next = right;
                right = right.next;
            }
            temp = temp.next;
        }
        if(left != null){
            temp.next = left;
        }
        if(right != null){
            temp.next = right;
        }
        return head.next;
    }
}

二叉树

二叉树的前序遍历

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> list = new ArrayList<>();
        dfs(root, list);
        return list;
    }

    public void dfs(TreeNode root, List<Integer> list){
        if(root == null){
            return;
        }
        list.add(root.val);
        dfs(root.left, list);
        dfs(root.right, list);
    }
}
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> list = new ArrayList<>();
        if(root==null) return list;

        LinkedList<TreeNode> stack = new LinkedList<>();
        TreeNode cur = root;
        while(!stack.isEmpty() || cur!=null){
            while(cur != null){
                list.add(cur.val);
                stack.push(cur);
                cur=cur.left;
            }
            TreeNode temp = stack.pop();
            if(temp.right != null){
                cur = temp.right;
            }
        }
        return list;
    }
}

中序遍历

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> list = new ArrayList<>();
        if(root == null) return list;
        
        LinkedList<TreeNode> stack = new LinkedList<>();
        TreeNode cur = root;
        
        while(!stack.isEmpty() || cur!=null){
            while(cur!=null){
                stack.push(cur);
                cur = cur.left;
            }
            TreeNode temp = stack.pop();
            list.add(temp.val);
            if(temp.right!=null){
                cur = temp.right;
            }
        }
        return list;
    }
}

后序遍历

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<>();
        postOrder(root, res);
        return res;
    }
    public void postOrder(TreeNode root, List<Integer> list){
        if(root == null){
            return;
        }
        postOrder(root.left, list);
        postOrder(root.right, list);
        list.add(root.val);
    }
}
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<>();
        if(root == null) return res;
        
        LinkedList<TreeNode> stack = new LinkedList<>();
        TreeNode prev = null;
        
        while(!stack.isEmpty() || root!=null){
            while(root != null){
                stack.push(root);
                root = root.left;
            }
            root = stack.pop();
            if(root.right == null || root.right == prev){
                res.add(root.val);
                prev = root;
                root = null;
            }else{
                stack.push(root);
                root = root.right;
            }
        }
        return res;
    }
}

层序遍历

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> res = new ArrayList();
        if(root==null) return res;
        Queue<TreeNode> queue = new LinkedList();
        queue.add(root);
        
        while(!queue.isEmpty()){
            int size = queue.size();
            List<Integer> list = new ArrayList();
            for(int i=0; i<size; 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;
    }
}

对称二叉树

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public boolean isSymmetric(TreeNode root) {
        if(root==null || (root.left==null&&root.right==null)) return true;
        return cur(root.left, root.right);
    }

    public boolean cur(TreeNode left, TreeNode right){
        if(left==null && right==null) return true;
        if(left==null || right==null) return false;
        if(left.val!=right.val) return false;

        return cur(left.left, right.right)&cur(left.right, right.left);
    }
}
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public boolean isSymmetric(TreeNode root) {
        if(root==null || (root.left==null && root.right==null)) return true;
        LinkedList<TreeNode> stack = new LinkedList();
        stack.add(root.left);
        stack.add(root.right);

        while(stack.size()>0){
            TreeNode left = stack.poll();
            TreeNode right = stack.poll();
            if(left==null && right==null) continue;
            if(left==null || right==null) return false;
            if(left.val != right.val) return false;

            stack.offer(left.left);
            stack.offer(right.right);

            stack.offer(left.right);
            stack.offer(right.left);
        }
        return true;
    }
}

LRU缓存

class LRUCache {
//双向链表+hashmap
    int capacity;
    int size;
    Map<Integer,Node>hashTable;

    Node head;
    Node tail;
    
    public LRUCache(int capacity) {
        this.capacity=capacity;
        this.size=0;
        hashTable=new HashMap();
 
        head=new Node();
        tail=new Node();
        head.next=tail;
        tail.pre=tail;
    }
    
    public int get(int key) {
      Node node = hashTable.get(key);
      if(node==null)return -1;
      //将node移动到头部
      moveToHead(node);
      return node.value;
    }

    public void moveToHead(Node node){
        //将node从双向链表删除
        removeNode(node);
        //将node添加到头节点后面
        addToHead(node);
    }

    public Node removeNode(Node node){
        Node preNode=node.pre;
        Node nextNode=node.next;

        preNode.next=nextNode;
        nextNode.pre=preNode;
        node.next=null;
        node.pre=null;
        return node;
    }

    public void addToHead(Node node){
        Node nextNode=head.next;
        head.next=node;
        node.pre=head;

        node.next=nextNode;
        nextNode.pre=node;
    }

    
    public void put(int key, int value) {

         Node node= hashTable.get(key);
         if(node!=null){
            node.value=value;
            moveToHead(node);
            return;
         }
         //添加到缓存
         node=new Node(key,value);
         hashTable.put(key,node);
         //新节点添加到头节点
         addToHead(node);
         //
         this.size++;
         if(this.size>this.capacity){
             Node rnode=removeTail();
             hashTable.remove(rnode.key);
             this.size--;
         }
    }

    public Node removeTail(){
        Node rnode=tail.pre;
       return removeNode(rnode);
    }
    

    class Node{
        int key;
        int value;
        Node next;
        Node pre;

        Node(){};
        Node(int key,int value){
            this.key=key;
            this.value=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);
 */

双指针

早餐组合

class Solution {
    public int breakfastNumber(int[] staple, int[] drinks, int x) {
        Arrays.sort(staple);
        Arrays.sort(drinks);
        int count = 0;
        int left = 0;
        int right = drinks.length-1;
        while(left<staple.length&&right>=0){
            int number = staple[left]+drinks[right];
            if(number<=x){
                count = (count+right+1)%1000000007;
                left++;
            }else{
                right--;
            }
        }
        return count;
    }
}

删除有序数组中的重复项

class Solution {
    public int removeDuplicates(int[] nums) {
        if(nums.length==0)
            return 0;
        //计数
        int counter = 0;
        for(int i=0;i<nums.length;i++){
            if(nums[i]!=nums[counter]){
                counter++;
                nums[counter]=nums[i];
            }
        }
        counter+=1;
        return counter;
    }
}

移除元素

class Solution {
    public int removeElement(int[] nums, int val) {
        int index = 0;
        for(int i=0; i<nums.length; i++){
            if(nums[i]!=val){
                nums[index] = nums[i];
                index+=1;
            }
        }
        return index;
    }
}

重排链表

/**
 * 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 void reorderList(ListNode head) {
        if(head==null) return;
       // 用空间换时间
        ArrayList<ListNode> list = new ArrayList();
        ListNode cur = head;
        while(cur!=null){
            list.add(cur);
            cur = cur.next;
        }
        int size = list.size();
        int i = 0;
        int j = size - 1;
        while(i<j){
            list.get(i).next = list.get(j);
            i++;
            list.get(j).next = list.get(i);
            j--;
        }
        // 防止成环
        list.get(i).next = 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 void reorderList(ListNode head) {
        // 取中间断开,后半段逆序合并
        if(head==null) return;

        // 找中间节点
        ListNode slow=head, fast=head;
        while(fast.next!=null&&fast.next.next!=null){
            slow = slow.next;
            fast = fast.next.next;
        }
        ListNode mid = slow;

        ListNode l1 = head, l2 = mid.next;
        mid.next = null;  // 防止产生环
        l2 = reverse(l2);
        merge(l1, l2);
    }

    public ListNode reverse(ListNode node){
        ListNode pre = null;
        ListNode cur = node;
        while(cur!=null){
            ListNode nextNode = cur.next;
            cur.next = pre;
            pre = cur;
            cur = nextNode;
        }
        return pre;
    }

    public void merge(ListNode l1, ListNode l2){
        while(l1!=null&&l2!=null){
            ListNode next1 = l1.next;
            ListNode next2 = l2.next;
            l1.next = l2;
            l1 = next1;
            l2.next = l1;
            l2 = next2;
        }
    }
}

合并两个数组

class Solution {
    public void merge(int[] nums1, int m, int[] nums2, int n) {
        int len1 = m-1;
        int len2 = n-1;
        int len = m+n-1;
        while(len1>=0 && len2>=0){
            nums1[len--] = nums1[len1] > nums2[len2]?nums1[len1--]:nums2[len2--];
        }
        System.arraycopy(nums2,0,nums1,0,len2+1);
    }
}

逆向双指针:

class Solution {
    public void merge(int[] nums1, int m, int[] nums2, int n) {
        int p1=m-1,p2=n-1;
        int tail = m+n-1;
        int cur;
        while(p1>=0 || p2>=0){
            if(p1==-1){
                cur = nums2[p2--];
            }else if(p2==-1){
                cur = nums1[p1--];
            }else if(nums1[p1]>nums2[p2]){
                cur = nums1[p1--];
            }else{
                cur = nums2[p2--];
            }
            nums1[tail--] = cur;
        }
    }
}

移动零

class Solution {
    public void moveZeroes(int[] nums) {
        if(nums.length==1) return;
        int cur = 0, index = 0;
        while(cur < nums.length){
            if(nums[cur]!=0){
                swap(nums, cur, index);
                index++;
            }
            cur++;
        }
    }

    public void swap(int[] nums, int x, int y){
        int temp = nums[x];
        nums[x] = nums[y];
        nums[y] = temp;
    }
}

滑动窗口

https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/solution/hua-dong-chuang-kou-by-powcai/

无重复字符的最长子串

class Solution {
    public int lengthOfLongestSubstring(String s) {
        if(s.length() == 0) return 0;
        HashMap<Character, Integer> map = new HashMap<Character, Integer>();
        int max = 0;
        int left = 0;
        for(int i=0; i < s.length(); i++){
            if(map.containsKey(s.charAt(i))){
                left = Math.max(left, map.get(s.charAt(i))+1);
            }
            map.put(s.charAt(i), i);
            max = Math.max(max, i-left+1);
        }
        return max;
    }
}
class Solution {
    public int lengthOfLongestSubstring(String s) {
        int i=0;
        int flag = 0;
        int length = 0;
        int result = 0;
        while(i<s.length()){
            int pos = s.indexOf(s.charAt(i),flag);
            if(pos<i){
                if(length>result){
                    result = length;
                }
                if(result>=s.length()-pos-1){
                    return result;
                }
                length = i-pos-1;
                flag = pos+1;
            }
            length++;
            i++;
        }
        return length;
    }
}

位运算

2的幂

class Solution {
    public boolean isPowerOfTwo(int n) {
       if(n==0) return false;
       while((n&1)==0){
           n=n>>1;
       } 
       return n==1;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值