美文网首页
面试算法题

面试算法题

作者: Y了个J | 来源:发表于2021-03-26 23:16 被阅读0次

    排序:选择排序,冒泡排序,快排,堆排,希尔排序

    //选择,空间复杂度O(1),时间复杂度为O(n^2)
    public static void sort(int[] nums) {
            for (int i = 0; i < nums.length - 1; i++) {
                for (int j = i + 1; j < nums.length; j++) {
                    if (nums[i] > nums[j]) {
                        int tmp = nums[j];
                        nums[j] = nums[i];
                        nums[i] = tmp;
                    }
                }
            }
        }
    
    //冒泡,空间复杂度O(1),时间复杂度为O(n^2)
    public static void sort(int[] nums) {
            for (int i = 0; i < nums.length; i++) {
                for (int j = i; j < nums.length - i - 1; j++) {
                    if (nums[j] > nums[j + 1]) {
                        int tmp = nums[j];
                        nums[j] = nums[j + 1];
                        nums[j + 1] = tmp;
                    }
                }
            }
        }
    
    //快速排序是一种不稳定的排序方法。空间复杂度O(logn) 或 O(n)
    //时间复杂度O(nlogn) 或者 O(n^2) 
    public static void sort(int[] nums, int low, int hight) {
            int left = low;
            int right = hight;
            int key = nums[left];
            while (left < right) {
                // 先从右往左找到比key小的,有的话就放到key的位置上,当前这个位置后面就可以进行覆盖
                while (left < right && nums[right] >= key) {
                    right--;
                }
                nums[left] = nums[right];
                // 再从左往右找到比key大的数,覆盖到刚才那个 right 位上
                while (left < right && nums[left] <= key) {
                    left++;
                }
                nums[right] = nums[left];
            }
            nums[left] = key;
            // 排完后,key左边的数都比key小,key右边的数都比key大,然后就可以分别再把key左右部分进行这样排序
            sort(nums, low, left - 1);
            sort(nums, right + 1, hight);
        }
    

    反转链表

    public static ListNode reverseList(ListNode head) {
        ListNode pre = null;
        while (null != head) {
            ListNode next = head.next;
            head.next = pre;
            pre = head;
            head = next;
        }
        return pre;
    }
    
    // 递归法 1->2->3->4->null
    public static ListNode reverseList(ListNode head) {
        if (null == head && head.next == null) {
            return head;
        }
        ListNode newHead = reverseList(head.next);
        head.next.next = head;//head.next不为null
        head.next = null;
        return newHead;
    }
    

    删除链表的倒数第N个节点

    public ListNode removeNthFromEnd(ListNode head, int n) {
            ListNode node = new ListNode(0,head);
            int len = 0;
            while (head != null) {
                len++;
                head = head.next;
            }
            head = node;
            for (int i = 0; i < len-n; i++) {
                head = head.next;
            }
            ListNode next = head.next;
            head.next = next.next;
            next.next = null;
            return node.next;
        }
    

    数组中第K个最大元素

    public int findKthLargest(int[] nums, int k) {
            int len = nums.length;
            Arrays.sort(nums);
            return nums[len - k];
        }
    

    翻转数字

    static int reverseNum(int num) {
            int res = 0;
            while (num != 0) {
                int i = num % 10;
                res = res * 10 + i;
                num = num / 10;
            }
            return res;
        }
    

    翻转字符串

    static String reverseString(String s) {
            char[] chars = s.toCharArray();
            char[] chars2 = new char[chars.length];
            int j = 0;
            for (int i = chars.length - 1; i >= 0; i--) {
                chars2[j] = chars[i];
                j++;
            }
            return new String(chars2);
        }
    
    static String reverseString2(String s) {
            char[] chars = s.toCharArray();
            int n = chars.length;
            int j = chars.length / 2;
            for (int i = 0; i < j; i++) {
                char tmp = chars[i];
                chars[i] = chars[n - 1 - i];
                chars[n - 1 - i] = tmp;
            }
            return new String(chars);
        }
    

    判断回文数,121,1221

    public static boolean isPalindrome(int k) {
            String string = String.valueOf(k);
            int len = string.length();
            int mid = len / 2;
            for (int i = 0; i <= mid; i++) {
                char c1 = string.charAt(i);
                char c2 = string.charAt(len - 1 - i);
                if (c1 != c2) {
                    return false;
                }
            }
            return true;
        }
    
    public static boolean isPalindrome2(int x) {
            if (x < 0) return false;
            int div = 1;
            while (x / div >= 10) {
                div = div * 10;
            }
            while (x > 0) {
                int n1 = x % 10;//个位数
                int n2 = x / div;//高位数
                if (n1 != n2) {
                    return false;
                }
                x = x % div;//去除高位
                x = x / 10;//去除个位
                div = div / 100;
            }
            return true;
        }
    

    最长回文字符串
    判断有效括号,{[()]}

        public static boolean isValid(String s) {
            Stack<Character> stack = new Stack<>();
            for (char c : s.toCharArray()) {
                if (c == '{') {
                    stack.push('}');
                } else if (c == '[') {
                    stack.push(']');
                } else if (c == '(') {
                    stack.push(')');
                } else if (stack.isEmpty() || stack.pop() != c) {//不是 {[( 那就一定得是 )]}
                    return false;
                }
            }
            return true;
        }
    
    public boolean isValid2(String s) {
            if (s == null || s.length() == 0) return false;
            while (s.contains("{}") || s.contains("[]") || s.contains("()")) {
                s = s.replace("{}", "");
                s = s.replace("()", "");
                s = s.replace("[]", "");
            }
            return s.isEmpty();
        }
    

    括号的分数(())()

    //有效的括号的分数 (())()
        public static int score(String s) {
            Stack<Integer> stack = new Stack<>();
            stack.push(0);
            for (char c : s.toCharArray()) {
                if (c == '(') {
                    stack.push(0);
                } else {
                    int v1 = stack.pop();
                    int v2 = stack.pop();
                    stack.push(v2 + Math.max(1, v1 * 2));
                }
            }
            return stack.pop();
        }
    

    括号分数升级版 {()}()[]
    最长有效括号
    判断链表是否有环

    public static boolean hasCycle(ListNode node) {
            Set<ListNode> set = new HashSet<>();
            while (node != null) {
                boolean sus = set.add(node);
                if (!sus) {//HashSet有重复的添加会返回false
                    return true;
                }
                node = node.next;
            }
            return false;
        }
    
    //判断是否是环链,快慢指针
        private static boolean hasCycle2(ListNode head) {
            if (head == null || head.getNext() == null) {
                return false;
            }
            ListNode slow = head;
            ListNode fast = head.getNext();
            while (slow != fast) {
                if (fast == null || fast.getNext() == null) {
                    return false;
                }
                slow = slow.getNext();
                fast = fast.getNext().getNext();
            }
            return true;
        }
    

    二叉树前序,中序,后序遍历

    public void preOrder(ListNode node) {
            if (node == null) return;
            System.out.println(node.getVal());
            preOrder(node.left);
            preOrder(node.right);
        }
    
    public void inOrder(ListNode node) {
            if (node == null) return;
            inOrder(node.left);
            System.out.println(node.getVal());
            inOrder(node.right);
        }
    
    public void postOrder(ListNode node) {
            if (node == null) return;
            postOrder(node.left);
            postOrder(node.right);
            System.out.println(node.getVal());
        }
    

    层序遍历

    public static void levelSort(ListNode node) {
            Queue<ListNode> queue = new LinkedList<>();
            queue.add(node);
            int size = queue.size();
    
            StringBuilder levelPath = new StringBuilder();
            while (!queue.isEmpty()) {
                size--;
                ListNode n = queue.remove();
                levelPath.append(n.getVal().toString());
                if (n.left != null) {
                    queue.add(n.left);
                }
                if (n.right != null) {
                    queue.add(n.right);
                }
                if (size == 0) {
                    size = queue.size();
                    System.out.println(levelPath.toString());
                    levelPath = new StringBuilder();
                }
            }
        }
    

    打印所有树路径

    public static void printAllPath(ListNode node) {
            Queue<ListNode> queue = new LinkedList<>();
            queue.add(node);
    
            Queue<String> pathQ = new LinkedList<>();
            pathQ.add(node.getVal().toString());
    
            List<String> pathList = new ArrayList<>();
            while (!queue.isEmpty()) {
                ListNode n = queue.remove();
                String path = pathQ.remove();
                
                if (n.left == null && n.right == null) {
                    pathList.add(path);//叶子节点
                } else {
                    if (n.left != null) {
                        queue.add(n.left);
                        pathQ.add(path + n.left.val);
                    }
                    if (n.right != null) {
                        queue.add(n.right);
                        pathQ.add(path + n.right.val);
                    }
                }
            }
    
            System.out.println(pathList.toString());
        }
    

    一个字符串里最长不重复子串
    一个字符串里最长不重复子串的长度
    最大连续数之和
    最大子序和
    买卖股票的最佳时机
    不用Math函数实现开根
    接雨水
    数组里两数之和等于给定的值

    static int[] twoNumSum(int[] nums, int target) {
            for (int i = 0; i < nums.length - 1; i++) {
                for (int j = i + 1; j < nums.length; j++) {
                    if (nums[i] + nums[j] == target) {
                        return new int[]{nums[i], nums[j]};
                    }
                }
            }
            return new int[]{};
        }
    
    static int[] twoNumSum2(int[] nums, int target) {
            Map<Integer, Integer> map = new HashMap<>();
            for (int i = 0; i < nums.length; i++) {
                Integer num = target - nums[i];
                Integer n = map.get(num);
                if (n != null) {
                    return new int[]{nums[i], n};
                } else {
                    map.put(nums[i], nums[i]);
                }
            }
            return new int[]{};
        }
    

    三数之和

    public static void threeSum(int[] nums, int k) {
            if (nums == null || nums.length < 3) {
                return;
            }
            Arrays.sort(nums);
            for (int i = 0; i < nums.length - 2; i++) {
                int target = k - nums[i];
                int left = i + 1;
                int right = nums.length - 1;
                while (left < right) {
                    if (nums[left] + nums[right] == target) {
                        System.out.println(nums[i] + "+" + nums[left] + "+" + nums[right] + "=" + k);
                        break;
                    } else if (nums[left] + nums[right] > target) {
                        right--;
                    } else {
                        left++;
                    }
                }
            }
        }
    

    柱形图最大面积
    最大矩形面积
    最大正方形面积
    二分查找法

    //时间复杂度O(log2n)
    static int binarySerach(int[] nums, int key) {
            Arrays.sort(nums);
            int left = 0;
            int right = nums.length-1;
            while (left <= right) {
                int mid = (left + right) / 2;
                if (key > nums[mid]) {
                    left = mid + 1;
                } else if (key < nums[mid]) {
                    right = mid - 1;
                } else {
                    return mid;
                }
            }
        }
    

    爬楼梯
    将两个升序链表合并为一个新的 升序 链表并返回
    两线程分别打印奇偶数
    三线程顺序打印ABC
    10个线程打印1~100,打印要从小到大
    字符串转数值
    环形数组,数组里从第n个位置开始往往后移动,n最终到数组的第一位置
    LinkedHashMap 实现 LRU
    滑动窗口代码实现
    漏桶、令牌桶代码实现
    分发糖果
    不用Math函数开根

    设计个抢红包算法

    相关文章

      网友评论

          本文标题:面试算法题

          本文链接:https://www.haomeiwen.com/subject/kwzshltx.html