算法题-02-16

import uitls.Node;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;

public class test_02_16 {
    //1:无重复字长的最长子串-双指针
    public int lengthOfLongestSubstring(String s) {
        if (s.length()<=1){
            return s.length();
        }
        int max=0;
        int j_0=0;
        for (int i=1;i<s.length();i++){
            int j=i-1;
            //从i遍历至0
            for (;j>=j_0;j--){
                if (s.charAt(i)==s.charAt(j)){
                    j_0=j+1;
                    break;
                }
            }
            max=Math.max(max, i-j);
        }
        return max;
    }

    //反转链表
    public static Node test1(Node head){
        if (head==null){
            return null;
        }
        Node pre = null;
        Node p = head;
        Node pp= head.getNext();
        while (pp!=null){
            p.setNext(pre);
            pre = p;
            p = pp;
            pp = pp.getNext();
        }
        p.setNext(pre);
        head = p;
        return head;
    }
    //反转链表递归解法
    public static Node test2(Node head){
        if (head==null||head.getNext()==null){
            return head;
        }
        Node newHead = test2(head.getNext());
        head.getNext().setNext(head);
        head.setNext(null);
        return newHead;
    }
    //数组中第k个最大元素-采取勘探
    public static int test3(int[] nums,int k){
        int max = Integer.MIN_VALUE;
        for (int i=0;i<nums.length;i++){
            if (nums[i]>max){
                max = nums[i];
            }
        }
        int[] arr = new int[max+1];
        for (int i=0;i<nums.length;i++){
            arr[nums[i]]++;
        }
        System.out.println(Arrays.toString(arr));
        int count=0;
        for (int i=arr.length-1;i>=0;i--){
            count += arr[i];
            if (count>=k){
                return i;
            }
        }
        return -1;
    }


    //K个一组翻转链表 采取test5
    public static Node test4(Node head, int k){
        int count = 0;
        Node p = head;
        while (p!=null){
            count++;
            p=p.getNext();
        }
        Node res = head;

        Node left = head;
        Node right = head;
        //这里标记第几轮
        for (int i=0;i<count/k;i++){
            int kk = k;
            //移动至正确位置
            while (--kk>0){
                right=right.getNext();
            }
            //进行论转
            Node node = test5(res, left, right);
            if (i==0){
                res = node;
            }
            //移动至下一道
            left = left.getNext();
            right = left;
        }
        return res;
    }
    //给出Left和right节点 反转中间的节点 给定区间的反转
    public static Node test5(Node head, Node left, Node right){
        //s执行其前面一个节点
        Node s;
        if (left==head){
            s=null;
        }else {
            s = head;
            while (s.getNext()!=left){
                s=s.getNext();
            }
        }
        Node pre= null;
        Node p = left;
        Node ss = p;
        Node pp = left.getNext();
        while (p!=right){
            p.setNext(pre);
            pre = p;
            p=pp;
            pp = pp.getNext();
        }
        //指向前面一个
        p.setNext(pre);
        if (s==null){
            ss.setNext(pp);
            head = p;
        }else{
            s.setNext(p);
            ss.setNext(pp);
        }
        return head;
    }
    //三数之和-锚点在左边-TODO
    public static List<List<Integer>> test6(int[] nums) {
        List<List<Integer>> ls = new ArrayList<>();
        // 先排序
        Arrays.sort(nums);

        for (int k=1; k<nums.length-1;k++){
            int i=0;
            int j=nums.length-1;
            if (nums[k]==0&&k!=1&&nums[k]==nums[k-1]){
                continue;
            }
            System.out.println(k);
            while (i<k&&j>k){
                if (nums[i]+nums[k]+nums[j]>0){
                    j--;
                }else if(nums[i]+nums[k]+nums[j]<0){
                    i++;
                }else{

                    ls.add(Arrays.asList(nums[i],nums[k], nums[j]));
                    while (i+1<k&&nums[i+1]==nums[i]){
                        i++;
                    }
                    while (j-1<k&&nums[j-1]==nums[j]){
                        j--;
                    }
                    i++;
                    j--;
                }
            }
        }
        return ls;
    }
    //最大子数组和
    public static void test8(int[] nums){
        //以i结尾的最大和
        int[] dp = new int[nums.length];

        dp[0] = nums[0];

        for (int i=1;i<nums.length;i++){
            dp[i]=Math.max(dp[i-1]+nums[i], nums[i]);
        }
        int asInt = Arrays.stream(dp).max().getAsInt();
        System.out.println(asInt);
    }
    public static void test9(int[] nums){
        //最大和
        int max = Integer.MIN_VALUE;
        //上一个结尾的最大值
        int last = nums[0];
        for (int i=1;i<nums.length;i++){
            last = Math.max(last+nums[i],nums[i]);
            max = Math.max(last, max);
        }
        System.out.println(max);
    }
    //快速排序
    public static void test10(int[] nums, int left, int right){
        if (left>=right){
            return;
        }
        //找出mid
        int i=left;
        int j=right;
        int target = nums[left];
        while (i<=j){
            if (nums[i]<=target){
                i++;
            }else if(nums[j]>target){
                j--;
            }else{
                //进行交换
                int temp = nums[i];
                nums[i]=nums[j];
                nums[j]=temp;
                i++;
                j--;
            }
        }
        //将其放入应该放的位置
        nums[left]=nums[j];
        nums[j]=target;

        test10(nums, left, j-1);
        test10(nums, j+1,right);
    }


    //合并两个有序链表-
    public static void test11(Node head1, Node head2){
        Node newHead = new Node(-1);
        Node k = newHead;
        Node p = head1;
        Node q = head2;
        while (p!=null&&q!=null){
            if (p.getData()<q.getData()){
                newHead.setNext(new Node(p.getData()));
                p=p.getNext();
            }else{
                newHead.setNext(new Node(q.getData()));
                q=q.getNext();
            }
            newHead = newHead.getNext();
        }
        while (p!=null){
            newHead.setNext(p);
            p=p.getNext();
            newHead = newHead.getNext();
        }
        while (q!=null){
            newHead.setNext(q);
            q=q.getNext();
            newHead = newHead.getNext();
        }
    }
    //最长回文子串-动态规划
    public static void test13(String s){
        int n = s.length();
        int[][] dp = new int[n][n];
        //初始化
        for (int i=0;i<n;i++){
            dp[i][i]=1;
        }
        for (int i=0;i<n-1;i++){
            if (s.charAt(i)==s.charAt(i+1)){
                dp[i][i+1]=1;
            }else{
                dp[i][i+1]=0;
            }
        }
        for (int k=2;k<n;k++){
            int j=k;
            while (j<n){
                if (s.charAt(j-k)==s.charAt(j)){
                    dp[j-k][j]=dp[j-k+1][j-1];
                }else{
                    dp[j-k][j]=0;
                }
                j++;
            }
        }
        System.out.println(Arrays.deepToString(dp));
    }
    public static void main(String[] args) {
        test13("babad");
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值