自用|自用|

一、选m个数和为n

    public static void main(String[] args) {
        int k=3;
        int n=9;
        List<List<Integer>> result = new ArrayList<>();
        LinkedList<Integer> path = new LinkedList<>();
        combinationSum3(k, n, result, path);
        System.out.println(result);
    }
    public static List<List<Integer>> combinationSum3(int k, int n,List<List<Integer>> result,LinkedList<Integer> path) {
        build(k,n, 1, 0,result,path);
        return result;
    }

    private static void build(int k, int n, int startIndex, int sum,List<List<Integer>> result,LinkedList<Integer> path) {

        if (sum > n) return;

        if (path.size() > k) return;

        if (sum == n && path.size() == k) {
            result.add(new ArrayList<>(path));
            return;
        }

        for(int i = startIndex; i <= 9; i++) {
            path.add(i);
            sum += i;
            build(k, n, i + 1, sum,result,path);
            sum -= i;
            path.removeLast();
        }
    }

二、判断回文字段_去除空格

    public static void main(String[] args) {
        String s="A m2an, a plan, a canal: Pana2ma";
        boolean palindrome = isPalindrome(s);
        System.out.println(palindrome);
    }
    //即需要只留下字母和数字进行比较
    public static boolean isPalindrome(String s) {
        int n = s.length();
        int left = 0, right = n - 1;
        while (left < right) {
            while (left < right && !Character.isLetterOrDigit(s.charAt(left))) {
                ++left;
            }
            while (left < right && !Character.isLetterOrDigit(s.charAt(right))) {
                --right;
            }

            if (Character.toLowerCase(s.charAt(left)) != Character.toLowerCase(s.charAt(right))) {
                    return false;
                }
                ++left;
                --right;

        }
        return true;
    }

三、最长不重复子串

    public static void main(String[] args) {
        String s="abcdddae";
        int res = lengthOfLongestSubstring(s);
        System.out.println(res);
    }
    public static int lengthOfLongestSubstring(String s) {
        // 哈希集合,记录每个字符是否出现过
        Set<Character> occ = new HashSet<Character>();
        int n = s.length();
        // 右指针,初始值为 -1,相当于我们在字符串的左边界的左侧,还没有开始移动
        int rk = -1, ans = 0;
        for (int i = 0; i < n; ++i) {
            if (i != 0) {
                // 左指针向右移动一格,移除一个字符
                occ.remove(s.charAt(i - 1));
            }
            while (rk + 1 < n && !occ.contains(s.charAt(rk + 1))) {
                // 不断地移动右指针
                occ.add(s.charAt(rk + 1));
                ++rk;

            }
            // 第 i 到 rk 个字符是一个极长的无重复字符子串
            ans = Math.max(ans, rk - i + 1);

        }
        return ans;
    }

四、输出两字符串的公共最长子字符串

    public static void main(String[] args) {
        String s1="abce";
        String s2="cabcc";
        int res=longestCommonSubsequence(s1,s2);
        System.out.println(res);
    }
    //输出重合子字符串长度
    public static int longestCommonSubsequence(String text1, String text2) {
        int m = text1.length(), n = text2.length();
        int[][] dp = new int[m + 1][n + 1];
        for (int i = 1; i <= m; i++) {
            char c1 = text1.charAt(i - 1);
            for (int j = 1; j <= n; j++) {
                char c2 = text2.charAt(j - 1);
                if (c1 == c2) {
                    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[m][n];
    }

五、重复的子字符串

    
    //KMP
    public static void main(String[] args) {
        String s="abcabce";
        boolean b = kmp(s);
        System.out.println(b);
    }
    public static boolean kmp(String pattern) {
        int n = pattern.length();
        int[] fail = new int[n];
        Arrays.fill(fail, -1);
        for (int i = 1; i < n; i++) {
            int j = fail[i - 1];
            //前后缀不相同时,j进行回退
            while (j != -1 && pattern.charAt(j + 1) != pattern.charAt(i)) {
                j = fail[j];
            }
            //前后缀相同时,得到这个i对应的最长前后缀长度数
            if (pattern.charAt(j + 1) == pattern.charAt(i)) {
                fail[i] = j + 1;
            }
        }
        return fail[n - 1] != -1 && n % (n - fail[n - 1] - 1) == 0;
    }



    //暴力
    public static void main(String[] args) {
        String s="ababc";
        boolean b = repeatedSubstringPattern(s);
        System.out.println(b);
    }
    public static boolean repeatedSubstringPattern(String s) {
        return (s + s).indexOf(s, 1) != s.length();
    }

六、找出超过序列长度一半的整数元素

    //Boyer-Moore 投票算法
    //关键点:能够确定这个数组里有超过长度一半的整数的前提下,才可用,如果没有的话无法输出null
    public static void main(String[] args) {
        int[] arr={1,2,2,2,2,2,5,7,8};
        int res=majorityElement(arr);
        System.out.println(res);
    }
    public static int majorityElement(int[] nums) {
        int count = 0;
        Integer candidate = null;

        for (int num : nums) {
            if (count == 0) {
                candidate = num;
            }
            count += (num == candidate) ? 1 : -1;
        }

        return candidate;
    }

七、二叉树的最近公共祖先

    public static void main(String[] args) {
        Integer[] arr = new Integer[]{3,5,1,6,2,0,8,null,null,7,4};
        TreeNode a=createTree(arr,0);
        TreeNode res=lowestCommonAncestor(a,a.left.left,a.left.right.left);
        System.out.println(res.val);
    }
    public static TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if (root == p || root == q || root == null) return root;
        //寻找左子树是否包含p和q
        TreeNode left = lowestCommonAncestor(root.left, p, q);
        //寻找右子树是否包含p和q
        TreeNode right = lowestCommonAncestor(root.right, p, q);
        // 如果left 和 right都不为空,说明此时root就是最近公共节点
        // 如果left为空,right不为空,就返回right,说明目标节点是通过right返回的,反之亦然。
        if (left != null && right != null) return root;
        if (left == null) return right;
        return left;
    }

    private static TreeNode createTree(Integer[] array,int index){
        TreeNode treeNode = null;
        if (index<array.length) {
            Integer value = array[index];
            if (value == null) {
                return null;
            }
            treeNode = new TreeNode(value);
            treeNode.left = createTree(array, 2*index+1);
            treeNode.right = createTree(array, 2*index+2);
            return treeNode;
        }
        return treeNode;
    }
    public static class TreeNode {
        int val;
        TreeNode left;
        TreeNode right;
        public TreeNode() {}
        public TreeNode(int val) {
            this.val = val;
        }
        public TreeNode(int val, TreeNode left, TreeNode right) {
            this.val = val;
            this.left = left;
            this.right = right;
        }
    }

八、反转字符串的单个单词

class Solution {
    public String reverseWords(String s) {
        // 除去开头和末尾的空白字符
        s = s.trim();
        // 正则匹配连续的空白字符作为分隔符分割
        List<String> wordList = Arrays.asList(s.split("\\s+"));
        Collections.reverse(wordList);
        return String.join(" ", wordList);
    }
}

九、树的类创建以及层序遍历

//创建二叉树类
public static class TreeNode {
        int val;
        TreeNode left;
        TreeNode right;
        public TreeNode() {}
        public TreeNode(int val) {
            this.val = val;
        }
        public TreeNode(int val, TreeNode left, TreeNode right) {
            this.val = val;
            this.left = left;
            this.right = right;
        }
    }


//数组->二叉树
private static TreeNode createTree(Integer[] array,int index){
        TreeNode treeNode = null;
        if (index<array.length) {
            Integer value = array[index];
            if (value == null) {
                return null;
            }
            treeNode = new TreeNode(value);
            treeNode.left = createTree(array, 2*index+1);
            treeNode.right = createTree(array, 2*index+2);
            return treeNode;
        }
        return treeNode;
    }
//二叉树的最近公共
    public static TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if (root == p || root == q || root == null) return root;
        //寻找左子树是否包含p和q
        TreeNode left = lowestCommonAncestor(root.left, p, q);
        //寻找右子树是否包含p和q
        TreeNode right = lowestCommonAncestor(root.right, p, q);
        // 如果left 和 right都不为空,说明此时root就是最近公共节点
        // 如果left为空,right不为空,就返回right,说明目标节点是通过right返回的,反之亦然。
        if (left != null && right != null) return root;
        if (left == null) return right;
        return left;
    }
public class 层序遍历 {
    public static void main(String[] args) {
        TreeNode a=new TreeNode(5);
        a.left=new TreeNode(4);
        a.right=new TreeNode(3);
        a.left.left=new TreeNode(2);
        a.left.right=new TreeNode(1);
        ArrayList<ArrayList<Integer>> res=levelOrder(a);
        System.out.println(res);
    }
    public static ArrayList<ArrayList<Integer>> levelOrder (TreeNode root) {
        // write code here
        ArrayList<ArrayList<Integer> > res = new ArrayList();
        if (root == null)
            //如果是空,则直接返回空数组
            return res;
        //队列存储,进行层次遍历
        Queue<TreeNode> q = new ArrayDeque<TreeNode>();
        q.add(root);
        while (!q.isEmpty()) {
            //记录二叉树的某一行
            ArrayList<Integer> row = new ArrayList();
            int n = q.size();
            //因先进入的是根节点,故每层节点多少,队列大小就是多少
            for (int i = 0; i < n; i++) {
                TreeNode cur = q.poll();
                row.add(cur.val);
                //若是左右孩子存在,则存入左右孩子作为下一个层次
                if (cur.left != null)
                    q.add(cur.left);
                if (cur.right != null)
                    q.add(cur.right);
            }
            //每一层加入输出
            res.add(row);
        }
        return res;
    }
}

十、合并两个有序数列

class Solution {
    public void merge(int[] nums1, int m, int[] nums2, int n) {
        int p1 = 0, p2 = 0;
        int[] sorted = new int[m + n];
        int cur;
        while (p1 < m || p2 < n) {
            if (p1 == m) {
                cur = nums2[p2++];
            } else if (p2 == n) {
                cur = nums1[p1++];
            } else if (nums1[p1] < nums2[p2]) {
                cur = nums1[p1++];
            } else {
                cur = nums2[p2++];
            }
            sorted[p1 + p2 - 1] = cur;
        }
        for (int i = 0; i != m + n; ++i) {
            nums1[i] = sorted[i];
        }
    }
}

 十一、链表

    public static void main(String[] args) {
        Node n1 = new Node(1);
        Node n2 = new Node(1);
        Node n3 = new Node(3);
        Node n4 = new Node(4);
        Node n5 = new Node(5);
        n1.next = n2;
        n2.next = n3;
        n3.next = n4;
        n4.next = n5;

        showLink(deleteDuplicates(n1));
    }

private static class Node {
        Integer value;
        Node next;
        public Node(){}
        public Node(Integer value) {
            this.value = value;
        }

    }
//合并两个有序链表
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        ListNode prehead = new ListNode(-1);

        ListNode prev = prehead;
        while (l1 != null && l2 != null) {
            if (l1.val <= l2.val) {
                prev.next = l1;
                l1 = l1.next;
            } else {
                prev.next = l2;
                l2 = l2.next;
            }
            prev = prev.next;
        }

        // 合并后 l1 和 l2 最多只有一个还未被合并完,我们直接将链表末尾指向未合并完的链表即可
        prev.next = l1 == null ? l2 : l1;

        return prehead.next;
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值