面试常见代码题目

目录

最长公共子序列

最长公共子串

最长上升子序列

最长连续上升子序列

最长公共前缀

最大子序列和

无重复字符的最长子串

大数相加

大数相乘

链表大数相加

两数之和

删除有序链表中的重复元素(只保留一个重复元素)

数组去重

一个数组奇偶分开,偶数在前奇数在后(不要求相对有序)

一个数组奇偶分开,偶数在前奇数在后(要求变换前后相对有序)

数组中除了两个数都只出现一次,其余的都只出现一次

数组topK

全排列

两个二叉树是否相等

二叉树最大值

二叉树第K大

树的前序中序后序递归非递归遍历

树变链表

树的路径总和

二叉树的最近公共祖先

快排,归并,冒泡

二分查找递归非递归

青蛙跳台阶

第一个只出现第一次的字符

凑硬币

01背包

买卖股票的最佳时机

括号匹配

进制转换


最长公共子序列

    public int lcs(String s1, String s2) {
        int len1 = s1.length();
        int len2 = s2.length();
        int[][] dp = new int[len1 + 1][len2 + 1];
        for (int i = 1; i <= len1; i++) {
            for (int j = 1; j <= len2; j++) {
                if (s1.charAt(i - 1) == s2.charAt(j - 1)) {
                    dp[i][j] = dp[i - 1][j - 1] + 1;
                }else{
                    dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
                }
            }
        }
        return dp[len1][len2];
    }

可参考:https://blog.csdn.net/qq_31881469/article/details/77892324 

最长公共子串

    public int lcs1(String s1, String s2) {
        int len1 = s1.length();
        int len2 = s2.length();
        int[][] dp = new int[len1 + 1][len2 + 1];
        int max = 0;
        for (int i = 1; i <= len1; i++) {
            for (int j = 1; j <= len2; j++) {
                if (s1.charAt(i - 1) == s2.charAt(j - 1)) {
                    dp[i][j] = dp[i - 1][j - 1] + 1;
                }else{
                    dp[i][j] = 0;
                }
                max = Math.max(dp[i][j], max);
            }
        }
        return max;
    }

最长上升子序列

300. 最长上升子序列

    public int lengthOfLIS(int[] nums) {
        if(nums == null || nums.length == 0) return 0;
        int[] dp = new int[nums.length];
        int max = 1;
        Arrays.fill(dp, 1);
        for (int i = 0; i < nums.length; i++) {
            for (int j = 0; j < i; j++) {
                if (nums[j]<nums[i]){
                    dp[i] =  Math.max(dp[i],dp[j] + 1);
                }
            }
            max = Math.max(dp[i], max);
        }
        return max;
    }

最长连续上升子序列

674. 最长连续递增序列

    public int findLengthOfLCIS(int[] nums) {
        if(nums == null || nums.length < 1) return 0;
        int[] dp = new int[nums.length];
        int max = 1;
        Arrays.fill(dp, 1);
        for (int i = 1; i < nums.length; i++) {
            if (nums[i] > nums[i - 1]) {
                dp[i] = dp[i-1]+1;
            }
            max = Math.max(dp[i], max);
        }
        return max;
    }

最长公共前缀

14. 最长公共前缀

    public String longestCommonPrefix(String[] strs) {
        if (strs.length == 0) return "";
        String prefix = strs[0];
        for (int i = 1; i < strs.length; i++)
            while (strs[i].indexOf(prefix) != 0) {
                prefix = prefix.substring(0, prefix.length() - 1);
                if (prefix.isEmpty()) return "";
            }
        return prefix;
    }

最大子序列和

53. 最大子序和

    public int maxSubArray(int[] nums) {
        if(nums == null || nums.length == 0) return 0;
        int max = nums[0],sum = 0;
        for(int i = 0; i < nums.length ; i++){
            if(sum > 0 ){
                sum += nums[i];
            }else{
                sum = nums[i];
            }
            max = Math.max(sum,max);
        }
        return max;
    }

无重复字符的最长子串

3. 无重复字符的最长子串

    public static int lengthOfLongestSubstring(String s) {
        Map<Character, Integer> map = new HashMap<>();
        int max = 0;
        int start = 0;
        for(int end = 0;end <s.length();end++) {
            char c = s.charAt(end);
            if (map.containsKey(c)) {
//                这里必须使用max函数,防止出现输入字符串是abba的这种情况,在最后一次发现a在map中的时候
//                查到的结果为map.get(c)=0,那么start= map.get(c)+1就是1,最后的结果为3,使用max函数
//                就是为了防止start指针后退。
                start = Math.max(start, map.get(c)+1);
            }
            map.put(c, end);
            max = Math.max(max, end - start + 1);
        }
        return max;
    }

大数相加

可以参考我的这篇文章 大数相加,大数相乘,下面的重新写的代码没有进行多次翻转,相对简单

    public static String add(String s1,String s2) {
        String res = "";
        int len1 = s1.length();
        int len2 = s2.length();
        int max = len1>len2?len1:len2;
//        用0补齐到相同长度,方便计算
        if(len1 < len2) {
            for (int i = 0; i < max - len1; i++) {
                s1 = "0" + s1;
            }
        }else {
            for (int i = 0; i < max - len2; i++) {
                s2 = "0" + s2;
            }
        }
        int c = 0;//进位
        for (int i = max - 1; i >= 0; i--) {
//            减0是可以直接拿到数字大小
            int temp = (s1.charAt(i) - '0') + (s2.charAt(i) - '0') + c;
            int cur = temp % 10;//这是进位后的个位数
            res = cur + res;//将这个数添加到结果中
            c = temp / 10;//进位
        }
        if(c>0) {//判断最后是否有进位大于0,如果有添加
            res = c + res;
        }
        return res;//直接输出,不用反转
    }

大数相乘

大数相加,大数相乘

链表大数相加

    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        ListNode head = new ListNode(0);
        ListNode cur = head,p1=l1,p2=l2;
        int carry = 0;
        while(p1 != null || p2 != null ){
            int x = p1!=null?p1.val:0;
            int y = p2!=null?p2.val:0;
            int sum = x+y+carry;
            carry = sum/10;
            cur.next = new ListNode(sum%10);
            cur = cur.next;
            if(p1!=null) p1 = p1.next;
            if(p2!=null) p2 = p2.next;
        }
        if(carry >0 ){
            cur.next = new ListNode(carry);
        }
        return head.next;
    }

两数之和

两数之和

    public int[] twoSum(int[] nums,int target){
	    HashMap<Integer,Integer> map = new HashMap<>();
	    for(int i = 0;i<nums.length;i++){
		    int tmp = target - nums[i];
		    if(map.containsKey(tmp)){
			    return new int[]{map.get(tmp),i};
		    }
		    map.put(nums[i],i);
	    }
        return new int[2];
    }

删除有序链表中的重复元素(只保留一个重复元素)

83. 删除排序链表中的重复元素

    public ListNode deleteDuplicates(ListNode head) {
        ListNode phead = new ListNode(0);
        phead.next = head;
        ListNode slow = phead,fast = head;
        while(fast!=null){
            while(fast.next != null && fast.val == fast.next.val) fast = fast.next;
            slow.next = fast;
            slow = slow.next;
            fast = fast.next;
        }
        return phead.next;
    }

数组去重

不考虑最终数组排完序后的数组元素,例如1,1,3,2,2,2,2,2,5,最终去重后数组的元素为1,3,2,5,2,2,2,2,5

    public void deleteDup(int[] nums) {
        if (nums == null || nums.length == 0) return;
        int fast = 0;
        int slow = 0;
        while (fast < nums.length) {
            while (fast + 1 < nums.length && nums[fast] == nums[fast + 1]) fast++;
            nums[slow++] = nums[fast++];
        }
    }

一个数组奇偶分开,偶数在前奇数在后(不要求相对有序)

可参考我的这篇文章给一个数组,把偶数放到左边,奇数放到右边(有序和无序)

    public void reOrderArray(int[] nums) {
        int less = 0;
        int more = nums.length-1;
        while (less < more) {
            while (nums[more] % 2 == 0) {
                swap(nums, more, less++);
            }
            more--;
        }
    }
    public  void swap(int[] arr, int i, int j) {
        int tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
    }

一个数组奇偶分开,偶数在前奇数在后(要求变换前后相对有序)

    public void reOrderArray(int[] array) {
        if ( array == null || array.length == 0 ) return;
        int left = 0;//从左向右最右边的奇数下标
        for (int i = 0; i < array.length; i++) {
            if (array[i] % 2 == 0) {
                int cur = i;//碰到的偶数
                while (cur > left) {//逐个交换位置
                    swap(array, cur, --cur);
                }
                left++;//交换完偶数下标向右移动
            }
        }
    }
    public  void swap(int[] arr, int i, int j) {
        int tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
    }

数组中除了两个数都只出现一次,其余的都只出现一次

260. 只出现一次的数字 III

参考这篇(Java)一个整型数组里除了两个数字之外,其他的数字都出现了偶数次。请写程序找出这两个只出现一次的数字。或者leetcode的下面这个回答,相对来说比较简单。

    public int[] singleNumber(int[] nums) {
        int xor = 0;
        for (int i : nums)// 一样的抵消,不一样的两个数字异或运算结果必定有一位是1
            xor ^= i;

        int mask = xor & (-xor);

        int[] ans = new int[2];
        for (int i : nums) {
            if ((i & mask) == 0)//== 0、 == mask 两种结果
                ans[0] ^= i;
            else
                ans[1] ^= i;
        }

        return ans;
    }

作者:spirit-9
链接:https://leetcode-cn.com/problems/single-number-iii/solution/java-yi-dong-yi-jie-xiao-lu-gao-by-spirit-9-9/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

数组topK

    public int topK(int[] nums, int k) {
        if (nums == null || k <0 || k>nums.length) return Integer.MIN_VALUE;
        PriorityQueue<Integer> queue = new PriorityQueue<>(k);
        for (int i = 0; i < nums.length; i++) {
            if (queue.size() == k) {
                if (queue.peek() < nums[i]) {
                    queue.poll();
                    queue.offer(nums[i]);
                }
            }else {
                queue.offer(nums[i]);
            }
        }
        int res = queue.peek();
        for (int item : queue) {
            res = queue.poll();
        }
        return res;
    }

全排列

46. 全排列,代码中的链接可以看详细讲解。

class Solution {
    public List<List<Integer>> permute(int[] nums) {

        List<List<Integer>> res = new ArrayList<>();
        int[] visited = new int[nums.length];
        backtrack(res, nums, new ArrayList<Integer>(), visited);
        return res;

    }

    private void backtrack(List<List<Integer>> res, int[] nums, ArrayList<Integer> tmp, int[] visited) {
        if (tmp.size() == nums.length) {
            res.add(new ArrayList<>(tmp));
            return;
        }
        for (int i = 0; i < nums.length; i++) {
            if (visited[i] == 1) continue;
            visited[i] = 1;
            tmp.add(nums[i]);
            backtrack(res, nums, tmp, visited);
            visited[i] = 0;
            tmp.remove(tmp.size() - 1);
        }
    }
}

作者:powcai
链接:https://leetcode-cn.com/problems/permutations/solution/hui-su-suan-fa-by-powcai-2/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

两个二叉树是否相等

100. 相同的树

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

二叉树最大值

这题思路就是通过中序遍历,使用优先队列PriorityQueue存储,设置优先队列的大小为1,最后直接可以弹出。

二叉树第K大

和上题的思路就是优先队列的大小设置为K。

树的前序中序后序递归非递归遍历

二叉树相关题目

树变链表

114. 二叉树展开为链表

下方链接中有详细思路讲解,很清晰。

public void flatten(TreeNode root) {
    while (root != null) { 
        //左子树为 null,直接考虑下一个节点
        if (root.left == null) {
            root = root.right;
        } else {
            // 找左子树最右边的节点
            TreeNode pre = root.left;
            while (pre.right != null) {
                pre = pre.right;
            } 
            //将原来的右子树接到左子树的最右边节点
            pre.right = root.right;
            // 将左子树插入到右子树的地方
            root.right = root.left;
            root.left = null;
            // 考虑下一个节点
            root = root.right;
        }
    }
}

作者:windliang
链接:https://leetcode-cn.com/problems/flatten-binary-tree-to-linked-list/solution/xiang-xi-tong-su-de-si-lu-fen-xi-duo-jie-fa-by--26/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

树的路径总和

112. 路径总和

    public boolean hasPathSum(TreeNode root, int sum) {
        if(root == null) return false;
        sum -= root.val;
        if(root.left == null && root.right == null){
            return sum == 0;
        }
        return hasPathSum(root.left,sum) || hasPathSum(root.right,sum);
    }

113. 路径总和 II 

    public List<List<Integer>> pathSum(TreeNode root, int sum) {
        List<List<Integer>> res = new ArrayList<>();
        helper(root, sum, res, new ArrayList<Integer>());
        return res;
    }

    private void helper(TreeNode root, int sum, List<List<Integer>> res, ArrayList<Integer> tmp) {
        if (root == null) return;
        tmp.add(root.val);
        if (root.left == null && root.right == null && sum - root.val == 0) res.add(new ArrayList<>(tmp));
        helper(root.left, sum - root.val, res, tmp);
        helper(root.right, sum - root.val, res, tmp);
        tmp.remove(tmp.size() - 1);
    }

作者:powcai
链接:https://leetcode-cn.com/problems/path-sum-ii/solution/dfs-by-powcai-2/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

二叉树的最近公共祖先

236. 二叉树的最近公共祖先

    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if(root == null || root == p || root == q) return root;
        TreeNode right = lowestCommonAncestor(root.right,p,q);
        TreeNode left = lowestCommonAncestor(root.left,p,q);
        if(left == null && right == null) return null;
        else if(left != null && right != null) return root;
        else return left == null?right:left;
    }

快排,归并,冒泡

归并排序、快速排序、堆排序---Java实现(带注释)

二分查找递归非递归

二分查找算法(递归与非递归两种方式)

青蛙跳台阶

70. 爬楼梯

    public int climbStairs(int n) {
        int[] dp = new int[n+1];
        dp[0] = dp[1] = 1;
        for(int i = 2; i <= n ;i++){
            dp[i] = dp[i-1]+dp[i-2];
        }
        return dp[n];
    }

第一个只出现第一次的字符

    public int firstUniqChar(String s) {
        int[] help = new int[256];
        for(int i = 0;i < s.length();i++){
            help[s.charAt(i)]++;
        }
        for(int i = 0;i<s.length();i++){
            if(help[s.charAt(i)] == 1)
                return i;
        }
        return -1;
    }

凑硬币

注意:下面的代码并没有解决凑不齐的情况。只是返回凑不齐时最多多少个

    public  int  sumCoin(int[] coins, int amount) {
        if (coins == null || coins.length < 1) return -1;
        int[] dp = new int[amount+1];
        dp[0] = 0;
        for (int i = 1; i <= amount; i++) {
            dp[i] = amount + 1;
            for (int coin : coins) {
                if (i >= coin) {
                    dp[i] = Math.min(dp[i - coin] + 1, dp[i]);
                }
            }
        }
        return dp[amount] >amount? -1 : dp[amount];
    }

01背包

多重背包问题和01背包问题

买卖股票的最佳时机

122. 买卖股票的最佳时机 II

    public int maxProfit(int[] prices) {
        if(prices.length == 0) return 0;
		int result = 0;
		for (int i = 0; i < prices.length-1; i++) {
            int temp = prices[i+1] - prices[i];
			if( temp>0) 
				result += temp;
		}
		return result;
    }

括号匹配

20. 有效的括号

    public boolean isValid(String s) {
        Map<Character, Character> map = new HashMap<>();
        Stack<Character> stack = new Stack<>();
        stack.push('#');
        map.put('(', ')');
        map.put('{', '}');
        map.put('[', ']');
        map.put('#', '#');
        for (int i = 0; i < s.length(); i++) {
            if (map.containsKey(s.charAt(i))) stack.push(s.charAt(i));
            else if (map.get(stack.pop()) != s.charAt(i)) return false;
        }   
        return stack.size() == 1;
    }

进制转换

进制转换

    public String transter(int m, int n) {
        StringBuilder sb = new StringBuilder();
        boolean flag = true;
        if (m < 0) {
            m = -m;
            flag = false;
        }
        while (m > 0) {
            int yu = m % n;
            if (yu > 9) {
                char temp = (char) (yu - 10 + 'A');
                sb.append(temp);
            }else {
                sb.append(yu);
            }
            m = m / n;
        }
        if (!flag) {
            sb.append("-");
        }
        return sb.reverse().toString();
    }

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值