NC41 最长无重复子数组/NC133链表的奇偶重排/NC116把数字翻译成字符串/NC135 股票交易的最大收益/NC126换钱的最少货币数/NC45实现二叉树先序,中序和后序遍历(递归)(代码片段

Posted Zephyr丶J

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了NC41 最长无重复子数组/NC133链表的奇偶重排/NC116把数字翻译成字符串/NC135 股票交易的最大收益/NC126换钱的最少货币数/NC45实现二叉树先序,中序和后序遍历(递归)(代码片段相关的知识,希望对你有一定的参考价值。

今天把这几道题做完,相当于复习一遍吧

NC41 最长无重复子数组

题目描述

给定一个数组arr,返回arr的最长无重复元素子数组的长度,无重复指的是所有数字都不相同。
子数组是连续的,比如[1,3,5,7,9]的子数组有[1,3],[3,5,7]等等,但是[1,3,7]不是子数组

思路

滑动窗口+哈希表

import java.util.*;


public class Solution {
    /**
     * 
     * @param arr int整型一维数组 the array
     * @return int整型
     */
    public int maxLength (int[] arr) {
        // write code here
        //滑动窗口+哈希表
        int l = arr.length;
        int left = 0;
        int right = 1;
        Set<Integer> set = new HashSet<>();
        set.add(arr[0]);
        int res = 1;
        while(right < l){
            while(left < right && set.contains(arr[right])){
                set.remove(arr[left]);
                left++;
            }
            res = Math.max(res, right - left + 1);
            set.add(arr[right]);
            right++;
        }
        return res;
    }
}

NC133链表的奇偶重排

题目描述

给定一个单链表,请设定一个函数,将链表的奇数位节点和偶数位节点分别放在一起,重排后输出。
注意是节点的编号而非节点的数值。
示例1
输入:
{1,2,3,4,5,6}

返回值:
{1,3,5,2,4,6}

说明:
1->2->3->4->5->6->NULL
重排后为
1->3->5->2->4->6->NULL

思路

我这里将原链表断开了,我觉得如果不断开的话,可能会形成环。
其实这里在重排的过程中已经断开了,不需要自己断开

import java.util.*;

/*
 * public class ListNode {
 *   int val;
 *   ListNode next = null;
 *   public ListNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param head ListNode类 
     * @return ListNode类
     */
    public ListNode oddEvenList (ListNode head) {
        // write code here
        if(head == null || head.next == null)
            return head;
        ListNode odd = head;
        ListNode even = head.next;
        //head.next = null;
        ListNode index = even.next;
        ListNode dummy = new ListNode(-1);
        ListNode start = even;
        dummy.next = odd;
        while(index != null){
            odd.next = index;
            even.next = index.next;
            odd = odd.next;
            even = even.next;
            //index.next = null;
            if(even == null)
                break;
            index = even.next;
        }
        odd.next = start;
        return dummy.next;
    }
}

NC116把数字翻译成字符串

题目描述

有一种将字母编码成数字的方式:'a'->1, 'b->2', ... , 'z->26'。

现在给一串数字,返回有多少种可能的译码结果
示例1
输入:
"12"

返回值:
2

说明:
2种可能的译码结果(”ab” 或”l”)

思路

注意特例 100 和 0

import java.util.*;


public class Solution {
    /**
     * 解码
     * @param nums string字符串 数字串
     * @return int整型
     */
    public int solve (String nums) {
        // write code here
        int l = nums.length();
        int[] dp = new int[l];
        if(nums.charAt(0) == '0')
            return 0;
        dp[0] = 1;
        int pre = nums.charAt(0) - '0';
        for(int i = 1; i < l; i++){
            int cur = nums.charAt(i) - '0';
            if(pre == 0 && cur == 0)
                return 0;
            dp[i] = dp[i - 1];
            if(pre > 0 && pre * 10 + cur <= 26 && cur != 0){
                if(i > 2)
                    dp[i] += dp[i - 2];
                else
                    dp[i] += 1;
            }
            pre = cur;
        }
        return dp[l - 1];
    }
}

NC135 股票交易的最大收益(二)

题目描述

你最多可以同时持有一只股票。但你最多只能进行两次交易(一次买进和一次卖出记为一次交易。买进和卖出均无手续费)。
示例1
[8,9,3,5,1,3]
返回值:
4

思路

典型dp问题,再回顾一下

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * 两次交易所能获得的最大收益
     * @param prices int整型一维数组 股票每一天的价格
     * @return int整型
     */
    public int maxProfit (int[] prices) {
        // write code here
        int l = prices.length;
        int[][] dp = new int[l][4];
        dp[0][0] = 0;    //第一次手中无股
        dp[0][1] = -prices[0];    //第一次手中有股
        dp[0][2] = 0;    //第二次无股
        dp[0][3] = -prices[0];    //第二次有股,初始化只是为了计算
        for(int i = 1; i < l; i++){
            dp[i][1] = Math.max(dp[i - 1][1], -prices[i]);    //先持股
            dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] + prices[i]);
            dp[i][3] = Math.max(dp[i - 1][3], dp[i - 1][0] - prices[i]);
            dp[i][2] = Math.max(dp[i - 1][2], dp[i - 1][3] + prices[i]);
        }
        return dp[l - 1][2];
    }
}

NC126换钱的最少货币数

题目描述

给定数组arr,arr中所有的值都为正整数且不重复。每个值代表一种面值的货币,每种面值的货币可以使用任意张,再给定一个aim,代表要找的钱数,求组成aim的最少货币数。
如果无解,请返回-1.
【要求】
时间复杂度O(n \\times aim)O(n×aim),空间复杂度On。
示例1
输入:
[5,2,3],20
返回值:
4

思路

完全背包

import java.util.*;


public class Solution {
    /**
     * 最少货币数
     * @param arr int整型一维数组 the array
     * @param aim int整型 the target
     * @return int整型
     */
    public int minMoney (int[] arr, int aim) {
        // write code here
        //完全背包
        int CONST = 500000;
        int l = arr.length;
        int[] dp = new int[aim + 1];
        Arrays.fill(dp, CONST);
        dp[0] = 0;
        for(int i = 0; i < l; i++){
            for(int j = arr[i]; j <= aim; j++){
                dp[j] = Math.min(dp[j], dp[j - arr[i]] + 1);
            }
        }
        return dp[aim] == CONST ? -1 : dp[aim];
    }
}

NC45实现二叉树先序,中序和后序遍历(递归)

题目描述

分别按照二叉树先序,中序和后序打印所有的节点。
示例1
输入:
{1,2,3}
返回值:
[[1,2,3],[2,1,3],[2,3,1]]

思路

import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 * }
 */

public class Solution {
    /**
     * 
     * @param root TreeNode类 the root of binary tree
     * @return int整型二维数组
     */
    List<Integer> list = new ArrayList<>();
    public int[][] threeOrders (TreeNode root) {
        // write code here
        preorder(root);
        inorder(root);
        postorder(root);
        int size = list.size();
        int index = 0;
        int[][] res = new int[3][size / 3];
        for(int i = 0; i < 3; i++){
            for(int j = 0; j < size / 3; j++){
                res[i][j] = list.get(index++);
            }
        }
        return res;
    }
    
    public void preorder(TreeNode root){
        if(root == null)
            return;
        list.add(root.val);
        preorder(root.left);
        preorder(root.right);
    }
    public void inorder(TreeNode root){
        if(root == null)
            return;
        inorder(root.left);
        list.add(root.val);
        inorder(root.right);
    }
    public void postorder(TreeNode root){
        if(root == null)
            return;
        postorder(root.left);
        postorder(root.right);
        list.add(root.val);
    }
}

以上是关于NC41 最长无重复子数组/NC133链表的奇偶重排/NC116把数字翻译成字符串/NC135 股票交易的最大收益/NC126换钱的最少货币数/NC45实现二叉树先序,中序和后序遍历(递归)(代码片段的主要内容,如果未能解决你的问题,请参考以下文章

最长无重复子数组

最长无重复子数组

java数据结构与算法之最长无重复子串问题

java数据结构与算法之最长无重复子串问题

leetcode-最长无重复子数组-79

牛客Top200---最长无重复子数组(java详解)