您的位置:首页 > 其它

【群视频】笔记 - 2015.06.03

2015-06-21 03:10 274 查看
[code]贪心策略
            ——刷题初期 先不要搞。


拼接所有字符串产生字典顺序最小的大字符串

例如字符串数组{c,a,b},按照a、b、c的顺序拼接后的大字符串为abc,是字典顺序最小的。

[code]package test;

import java.util.Arrays;
import java.util.Comparator;

class MergeComparator implements Comparator<String> {
    @Override
    public int compare(String arg0, String arg1) {
        return (arg0 + arg1).compareTo(arg1 + arg0);
    }

    public class MergeStringsLowestLexicography {

        public static String lowestString(String[] strs) {
            Arrays.sort(strs, new MergeComparator());
            String res = "";
            for (int i = 0; i != strs.length; i++) {
                res += strs[i];
            }
        return res;
    }

    public static void main(String[] args) {
        String[] strArr = { "jibw", "ji", "jp", "bw", "jibw" };
        String result = lowestString(strArr);
        System.out.println(result);

    }
}


从5随机到7随机及其扩展

【题目】 给定一个等概率随机产生1~5的随机函数rand1To5如下: public int rand1To5()

{

return (int) (Math.random() * 5) + 1; } 除此之外不能使用任何额外的随机机制,请用rand1To5实现等概率随机产生1~7的随机函数rand1To7。 【补充题目】

给定一个以p概率产生0,以1-p概率产生1的随机函数rand01p如下: public int rand01p() {

// you can change p as you like

double p = 0.83;

return Math.random() < p ? 0 : 1; } 除此之外不能使用任何额外的随机机制,请用rand01p实现等概率随机产生1~6的随机函数rand1To6。 【进阶题目】

给定一个等概率随机产生1~M的随机函数rand1ToM如下: public int rand1ToM(int m) {

return (int) (Math.random() * m) + 1; } 除此之外不能使用任何额外的随机机制。有两个输入参数分别为m和n,请用rand1ToM(m)实现等概率随机产生1~n的随机函数rand1ToN。

【题目】

[code]public int rand1To5() {
    return (int) (Math.random() * 5) + 1;
}

public int rand1To7() {
    int num = 0;
    do {
        num = (rand1To5() - 1) * 5 + rand1To5() - 1;
    } while (num > 20);
    return num % 7 + 1;
}


【补充题目】

[code]public int rand01() {
    int num;
    do {
        num = rand01p();
    } while (num == rand01p());
    return num == 1 ? 1 : 0;
}


【进阶题目】

已知1~M的随机,请实现1~N的随机。

[code]public int rand1ToM(int m) {
    return (int) (Math.random() * m) + 1;
}

public int rand1ToN(int n, int m) {
    int[] nMSys = getMSysNum(n - 1, m);
    int[] randNum = getRanMSysNumLessN(nMSys, m);
    return getNumFromMSysNum(randNum, m) + 1;
}

// 把value转成m进制的数
public int[] getMSysNum(int value, int m) {
    int[] res = new int[32];
    int index = res.length - 1;
    while (value != 0) {
        res[index--] = value % m;
        value = value / m;
    }
    return res;
}

// 等概率随机产生一个0~nMsys范围上的数,只不过是m进制表达的。
public int[] getRanMSysNumLessN(int[] nMSys, int m) {
    int[] res = new int[nMSys.length];
    int start = 0;
    while (nMSys[start] == 0) {
        start++;
    }
    int index = start;
    boolean lastEqual = true;
    while (index != nMSys.length) {
        res[index] = rand1ToM(m) - 1;
        if (lastEqual) {
            if (res[index] > nMSys[index]) {
                index = start;
                lastEqual = true;
                continue;
            } else {
                lastEqual = res[index] == nMSys[index];
            }
       }
        index++;
    }
    return res;
}

// 把m进制的数转成10进制
public int getNumFromMSysNum(int[] mSysNum, int m) {
    int res = 0;
    for (int i = 0; i != mSysNum.length; i++) {
        res = res * m + mSysNum[i];
    }
    return res;
}


【题目】 给定一个无序数组arr,求出需要排序的最短子数组长度。 例如: arr = [1,5,3,4,2,6,7]

返回4,因为只有[5,3,4,2]需要排序。

【解】:

时间复杂度: O(n)

额外空间复杂度: O(1)

先左→右,找出max

再右→左,找min

因为求的是需要排序的最短子数组长度。

[code]public int getMinLength(int[] arr) {
    if (arr == null || arr.length < 2) {
        return 0;
    }
    int min = arr[arr.length - 1];
    int noMinIndex = -1;
    for (int i = arr.length - 2; i != -1; i--) {
        if (arr[i] > min) {
            noMinIndex = i;
        } else {
            min = Math.min(min, arr[i]);
        }
   }
    if (noMinIndex == -1) {
        return 0;
    }
    int max = arr[0];
    int noMaxIndex = -1;
    for (int i = 1; i != arr.length; i++) {
        if (arr[i] < max) {
            noMaxIndex = i;
        } else {
            max = Math.max(max, arr[i]);
        }
    }
    return noMaxIndex - noMinIndex + 1;
}


最大的leftMax与rightMax之差的绝对值 【题目】

给定一个长度为N(N>1)的整型数组arr,可以划分成左右两个部分,左部分arr[0..K],右部分arr[K+1..N-1],K可以取值的范围是[0,N-2]。求这么多划分方案中,左部分中的最大值减去右部分最大值的绝对值,最大是多少?

例如[2,7,3,1,1],当左部分为[2,7],右部分为[3,1,1]时,左部分中的最大值减去右部分最大值的绝对值为4。当左部分为[2,7,3],右部分为[1,1]时,左部分中的最大值减去右部分最大值的绝对值为6。还有很多划分方案,但最终返回6。

【解】:

时间复杂度: O(n)

额外空间复杂度: O(1)

[code]public int maxABS3(int[] arr) {
    int max = Integer.MIN_VALUE;
    for (int i = 0; i < arr.length; i++) {
        max = Math.max(arr[i], max);
    }
    return max - Math.min(arr[0], arr[arr.length - 1]);
}


[code][方法一]:(不得分)
public int maxABS1(int[] arr) {
    int res = Integer.MIN_VALUE;
    int maxLeft = 0;
    int maxRight = 0;
    for (int i = 0; i != arr.length - 1; i++) {
        maxLeft = Integer.MIN_VALUE;
        for (int j = 0; j != i + 1; j++) {
            maxLeft = Math.max(arr[j], maxLeft);
        }
        maxRight = Integer.MIN_VALUE;
        for (int j = i + 1; j != arr.length; j++) {
            maxRight = Math.max(arr[j], maxRight);
        }
        res = Math.max(Math.abs(maxLeft - maxRight), res);
    }
    return res;
}


[code][方法二]:(空间换时间)
public int maxABS2(int[] arr) {
    int[] lArr = new int[arr.length];
    int[] rArr = new int[arr.length];
    lArr[0] = arr[0];
    rArr[arr.length - 1] = arr[arr.length - 1];
    for (int i = 1; i < arr.length; i++) {
        lArr[i] = Math.max(lArr[i - 1], arr[i]);
    }
    for (int i = arr.length - 2; i > -1; i--) {
        rArr[i] = Math.max(rArr[i + 1], arr[i]);
    }
    int max = 0;
    for (int i = 0; i < arr.length - 1; i++) {
        max = Math.max(max, Math.abs(lArr[i] - rArr[i + 1]));
    }
    return max;
}


现在有一种新的二叉树节点类型如下:

[code]public class Node {
    public int value;
    public Node left;
    public Node right;
    public Node parent;

    public Node(int data) {
        this.value = data;
    }
}


该结构比普通二叉树节点结构多了一条指向父节点的parent指针。假设有一棵Node类型的节点组成的二叉树,树中每个节点的parent指针都正确的指向自己的父节点,头节点的parent指向null。只给一个在二叉树中的某个节点node,请实现返回node的后继节点的函数。在二叉树的中序遍历的序列中,node的下一个节点叫做node的后继节点。

【解】:

[code]public Node getNextNode(Node node) {
    if (node == null) {
        return node;
    }
    if (node.right != null) {
        return getLeftMost(node.right);
    } else {
        Node parent = node.parent;
        while (parent != null && parent.left != node) {
        node = parent;
        parent = node.parent;
    }
    return parent;
}
}

public Node getLeftMost(Node node) {
    if (node == null) {
        return node;
    }
    while (node.left != null) {

        node = node.left;
    }
    return node;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: