2016年6月11日星期六

狂暴复习之路20160611 String I

344Reverse String
public String reverseString(String s) {
    return new StringBuilder(s).reverse().toString();
}
哈哈 开玩笑的,下面这个才是。 也可以写递归。
public String reverseString(String s) {
    char[] temp = s.toCharArray();
    for (int i = 0; i <temp.length/2 ; i++) {
        char x = temp[i];
        temp[i] = temp[temp.length-1-i];
        temp[temp.length-1-i] = x;
    }
    return new String(temp);
}
public int romanToInt(String s) {
    int result = 0;
    int iCount = 0;
    int vCount = 0;
    int xCount = 0;
    int lCount = 0;
    int cCount = 0;
    int dCount = 0;
    int mCount = 0;
    int ivCount = 0;
    int ixCount = 0;
    int xlCount = 0;
    int xcCount = 0;
    int cdCount = 0;
    int cmCount = 0;

    for (int i = 0; i < s.length();i++)
    {
        if (s.charAt(i) == 'I')
        {
            iCount++;
            if (i + 1 != s.length())
            {
                if (s.charAt(i + 1) == 'V')
                    ivCount++;
                if (s.charAt(i + 1) == 'X')
                    ixCount++;
            }

        } else if (s.charAt(i) == 'V')
        {
            vCount++;
        } else if (s.charAt(i) == 'X')
        {
            xCount++;
            if (i + 1 != s.length())
            {
                if (s.charAt(i + 1) == 'L')
                    xlCount++;
                if (s.charAt(i + 1) == 'C')
                    xcCount++;
            }
        } else if (s.charAt(i) == 'L')
        {
            lCount++;
        } else if (s.charAt(i) == 'C')
        {
            cCount++;
            if (i + 1 != s.length())
            {
                if (s.charAt(i + 1) == 'D')
                    cdCount++;
                if (s.charAt(i + 1) == 'M')
                    cmCount++;
            }
        } else if (s.charAt(i) == 'D')
        {
            dCount++;
        } else if (s.charAt(i) == 'M')
        {
            mCount++;
        }
    }
    result = iCount + 5 * vCount + 10 * xCount + 50 * lCount + 100 * cCount
            + 500 * dCount + 1000 * mCount - 2*ivCount - 2* ixCount - 20*xlCount-20*xcCount
            - 200* cdCount - 200*cmCount;
    return result;
}
没啥可说的,按位扫描。
12Integer to Roman
这个更没意思。
public String intToRoman(int num) {
    String result = "";
    int t = num/1000;
    int h = (num-t*1000)/100;
    int d = (num-t*1000-h*100)/10;
    int u = num-t*1000-h*100-d*10;
    if (num>0&&num<=3999)
    {
        result =
                numberToRoman(t,'M','*','*') +
                        numberToRoman(h,'C','D','M') +
                        numberToRoman(d,'X','L','C') +
                        numberToRoman(u,'I','V','X');
    }
    else    {
        result = null;
    }
    return result;
}

public String numberToRoman(int num, char o, char f, char t)
{
    String result = "";

    switch (num)
    {
        case 0:
        {
            break;
        }
        case 1:
        {
            result = result + o;
            break;
        }
        case 2:
        {
            result = result + o + o;
            break;
        }
        case 3:
        {
            result = result + o + o + o;
            break;
        }
        case 4:
        {
            result = result + o + f;
            break;
        }
        case 5:
        {
            result = result + f;
            break;
        }
        case 6:
        {
            result = result + f + o;
            break;
        }
        case 7:
        {
            result = result + f + o + o;
            break;
        }
        case 8:
        {
            result = result + f + o + o + o;
            break;
        }
        case 9:
        {
            result = result + o + t;
            break;
        }

    }
    return result;
}

22Generate Parentheses
其实我觉得这道题更应该放到DFS里面
public List<String> generateParenthesis(int n)
{
    if (n <= 0)
        return null;
    ArrayList<String> list = new ArrayList<String>();
    String str = new String();
    dfs(list, str, n, n);
    return list;
}

private void dfs(ArrayList<String> list, String str, int left, int right)
{
    if (left > right)
        return;
    if (left == 0 && right == 0)
    {
        list.add(str);
    }
    if (left > 0)
        dfs(list, str + "(", left - 1, right);
    if (right > 0)
        dfs(list, str + ")", left, right - 1);
}
345Reverse Vowels of a String
public String reverseVowels(String s) {
    char[] c = s.toCharArray();
    int l = 0;
    int r = c.length-1;
    while(l < r)
    {
        while (!val(c[l])&&l<r)
        {
            l++;
        }
        while (!val(c[r])&&l<r)
        {
            r--;
        }
        char temp = c[l];
        c[l] = c[r];
        c[r] = temp;
        l++;
        r--;
    }
    return new String(c);
}
public boolean val(char c)
{
    if (c=='a'||c=='A'||c=='e'||c=='E'||c=='i'||c=='I'||c=='o'||c=='O'||c=='u'||c=='U')
        return true;
    else        return false;
}
其实写的不太好,应该封装一个直接找出来的算法,稍微有点冗余。

20Valid Parentheses
public boolean isValid(String s) {
    Stack<Character> stack = new Stack();
    if (s==null||s.length()==0)
        return true;
    char[] temp = s.toCharArray();
    char poped = ' ';
    for (char c:temp)
    {
        switch (c)
        {
            case '(':{ stack.push(c);break;}
            case '[':{ stack.push(c);break;}
            case '{':{ stack.push(c);break;}
            case ')':{ if (stack.size()==0||stack.pop()!='(') return false;break;}
            case ']':{ if (stack.size()==0||stack.pop()!='[') return false;break;}
            case '}':{ if (stack.size()==0||stack.pop()!='{') return false;break;}
        }
    }
    return stack.size()==0?true:false;
}
利用栈,如果是前括号入栈,后括号出栈,并判断符号的正确性。

public String countAndSay(int n) {
    String temp = "1";
    for (int i = 1; i <n ; i++) {
        temp = nextString(temp);
    }
    return temp;
}
public String nextString(String s)
{
    int num = 1;
    char cur = s.charAt(0);
    StringBuilder bs = new StringBuilder();
    for (int i = 1; i < s.length(); i++) {
        if (s.charAt(i)==cur)
            num++;
        else        {
            bs.append(num);
            bs.append(cur);
            cur = s.charAt(i);
            num=1;
        }
    }
    bs.append(num);
    bs.append(cur);
    return bs.toString();
}
这题应该放到dp那里去,典型的简单dp问题。
58Length of Last Word
public int lengthOfLastWord(String s) {
    if (s==null||s.length()==0)
        return 0;
    String[] temp = s.split(" ");
    if (temp.length==0)
        return 0;
    return temp[temp.length-1].length();
}

2016年6月10日星期五

狂暴复习之路20160611 Greedy I

122Best Time to Buy and Sell Stock II
参见Array I
330Patching Array
public int minPatches(int[] nums, int n) {
    int result = 0;
    int index = 0;
    // currSum标记了当前数组nums可累加到的最大范围[1, currSum)    for (double currSum = 1; currSum <= n; )
    {
        // 数组内元素小于currSum时,可累加的sum上限增加为// currSum + nums[index],然后数组索引值加1        if (index < nums.length && nums[index] <= currSum)
            currSum += nums[index++];
        else        {
            currSum *= 2; // 添入元素后,可累加的sum范围加倍            ++result;
        }
    }
    return result;
}
55Jump Game
public boolean canJump(int[] nums) {
    if (nums == null || nums.length <= 1)
        return true;
int jump = nums[0]; for (int i = 0; i < nums.length; i++) { if (jump <= i && nums[i] == 0) return false; if (i + nums[i] > jump) { jump = i + nums[i]; } if (jump >= nums.length - 1) return true; } return false; }
贪出一片天,当jump>=nums.length-1的时候 立即返回true。

134Gas Station
public int canCompleteCircuit(int[] gas, int[] cost) {
    if (gas==null||gas.length==0)
        return -1;
    int sum = 0;
    int start = -1;
    int cur = 0;
    for (int i = 0; i <gas.length ; i++) {
        sum += gas[i] - cost[i];
        cur += gas[i] - cost[i];
        if (cur<0)
        {
            start = i;
            cur = 0;
        }
    }
    if (sum<0)
        return -1;
    else        return start+1;
}
如果某一个gas走不到,就从下一个开始,因为前面的路都没问题!而且这是一个circle。
45Jump Game II
public int jump(int[] nums) {
    int result = 0;
    int last = 0;
    int cur = 0;
    for (int i = 0; i <nums.length ; i++)
    {
        if (i>cur)
            return -1;
        if (i > last)
        {
            last = cur;
            result++;
        }
        cur = Math.max(cur,i+nums[i]);
    }
    return result;
}
贪心,每次都跳当前情况下的最远距离。

狂暴复习之路20160610 Dynamic Programming I

338Counting Bits
public int[] countBits(int num) {
    int[] result = new int[num+1];
    result[0] = 0;
    if (num!=0)
    {
        int flag = 0;
        for (int i =1; i<=num;i++)
        {
            result[i] = result[flag]+1;
            flag++;
            if (flag+1>num||result[flag+1]==0)
                flag=0;
            else                flag++;
        }
    }
    return result;
}
没啥好说的从头到尾扫描

343Integer Break
public int integerBreak(int n) {
    if (n == 2)
        return 1;
    if (n == 3)
        return 2;
    return (int)Math.pow(3, (n-2)/3)*((n-2)%3+2);
}
这道题的名字叫做 凑3.

96Unique Binary Search Trees
public int numTrees(int n) {
    int[] resultSet = new int[n+1];
    resultSet[0] = 1;
    resultSet[1] = 1;
    if (n<2)
        return resultSet[n];
    for (int i = 2; i <n ; i++) {
        int temp = 0;
        for (int j = 0; j <i ; j++) {
            temp += resultSet[j]*resultSet[i-1-j];
        }
        resultSet[i] = temp;
    }
    return resultSet[n];
}
最优子结构 Σ(根节点*左子树的个数*右子树的个数)
312Burst Balloons
public int DP (int l,int r,int[] nums,int[][] dp)
{
    if (dp[l][r] > 0)
        return dp[l][r];
    for (int x = l; x <= r; x++) {
        dp[l][r] = Math.max(dp[l][r], DP(l, x - 1, nums, dp) + nums[l - 1] * nums[x] * nums[r + 1] + 
DP(x + 1, r, nums, dp));
    }
    return dp[l][r];
}
public int maxCoins(int[] nums) {
    int n = nums.length;
    int[] temp = new int[n + 2];
    
    for (int i = 0; i < n; i++) 
        temp[i + 1] = nums[i];
    
    temp[0] = temp[n + 1] = 1;
    int[][] dp = new int[n + 2][n + 2];
    return DP(1, n, temp, dp);
}
从只剩1个气球开始想 最优子结构 dp[l][r] = Math.max(dp[l][r], DP(l, x - 1, nums, dp) + nums[l - 1] * nums[x] * 
nums[r + 1] + DP(x + 1, r, nums, dp));
309Best Time to Buy and Sell Stock with Cooldown
public int maxProfit(int[] prices) {
    if (prices == null || prices.length == 0)
        return 0;
    int len = prices.length;
    int[] sell = new int[len];
    int[] coolDown = new int[len];
    sell[0] = 0;
    coolDown[0] = 0;
    for (int i = 1; i < len; i++) {
        sell[i] = Integer.max(sell[i - 1] + prices[i] - prices[i - 1], coolDown[i - 1]);
        coolDown[i] = Integer.max(sell[i - 1], coolDown[i - 1]);
    }
    return Integer.max(sell[len - 1], coolDown[len - 1]);
}
最优子结构 Max= max(sell,coolDown),sell[i] = Integer.max(sell[i - 1] + prices[i] - prices[i - 1],
 coolDown[i - 1]);
coolDown[i] = Integer.max(sell[i - 1], coolDown[i - 1]);

70Climbing Stairs
public int climbStairs(int n) {
    if (n==0)
        return 0;
    if (n==1)
        return 1;
    if (n==2)
        return 2;
    int[] resultSet = new int[n+1];
    resultSet[0] = 0;
    resultSet[1] = 1;
    resultSet[2] = 2;
    for (int i =3; i<=n;i++)
    {
        resultSet[i] = resultSet[i-1]+resultSet[i-2];
    }
    return resultSet[n];
}
没啥可说的,resultSet[i] = resultSet[i-1]+resultSet[i-2];
53Maximum Subarray
参见Array I
62Unique Paths

public int uniquePaths(int m, int n) {
    if (m==0&&n==0)
        return 0;
    if (m==1&&n==1)
        return 1;
    int[][] resultSet = new int[m][n];
    for (int i = 0; i <m ; i++) {
        resultSet[i][0] = 1;
    }
    for (int i = 0; i <n ; i++) {
        resultSet[0][i] = 1;
    }
    for (int i = 1; i <m ; i++) {
        for (int j = 1; j <n ; j++) {
            resultSet[i][j] = resultSet[i-1][j] + resultSet[i][j-1];
        }
    }
    return resultSet[m-1][n-1];
}
最优子结构 resultSet[i][j] = resultSet[i-1][j] + resultSet[i][j-1];

121Best Time to Buy and Sell Stock
参见Array I

64Minimum Path Sum
public int minPathSum(int[][] grid) {
    int height = grid.length;
    int width = grid[0].length;
    for (int i = 0; i< height; i++)
        for (int j = 0; j<width ; j ++)
        {
            if (i==0&&j==0) {
                continue;
            }
            else if(i==0) {
                grid[i][j] += grid[i][j-1];
            }
            else if(j==0) {
                grid[i][j] += grid[i-1][j];
            }
            else {
                grid[i][j] += Math.min(grid[i-1][j],grid[i][j-1]);
            }
        }
    return grid[height-1][width-1];
}
从左到右,从上到下,选最小值叠加grid[i][j]=(grid[i][j]+Math.min(grid[i-1][j],grid[i][j-1]));

狂暴复习之路20160610 Array I

因为马上要去面试了,虽然说LeetCodeOJ上面已经刷了200道算法题,但是我打算再复习一遍,从今天开始。

1. Array

283Move Zeroes


public void moveZeroes(int[] nums) {
    int nonZeroIndex = 0;
    int zeroIndex = 0;
    int len = nums.length;

    while(nonZeroIndex < len)
    {
        if(nums[nonZeroIndex] == 0)
        {
            nonZeroIndex++;
            continue;
        }

        if(nonZeroIndex != zeroIndex)
        {
            nums[zeroIndex] = nums[nonZeroIndex];
            nums[nonZeroIndex] = 0;
        }
        zeroIndex++;
        nonZeroIndex++;
    }
}
不断地找出非0 与为0的点 交换他们的值


238Product of Array Except Self
从前向后一遍乘法 再从后向前一遍乘法
public int[] productExceptSelf(int[] nums) {
    int[] result = new int[nums.length];
    result[0] = 1;
    for (int i = 1; i <nums.length ; i++) {
        result[i] = result[i-1] * nums[i-1];
    }
    int temp = 1;
    for (int i = nums.length-1; i >=0 ; i--) {
        result[i] *= temp;
        temp *= nums[i];
    }
    return result;
}

121Best Time to Buy and Sell Stock
public int maxProfit(int[] prices) {
    int profit = 0;
    int min = Integer.MAX_VALUE;
    for(int i=0; i<prices.length; i++){
        profit = Math.max(profit, prices[i]-min);
        min = Math.min(min, prices[i]);
    }
    return profit;
}
动态规划,每次加入一个数字,计算加入这个数字之后对结果的影响

122Best Time to Buy and Sell Stock II

public int maxProfit(int[] prices) {
    int result = 0;
    int benefit = 0;
    for (int i = 1; i <prices.length ; i++) {
        benefit = prices[i] - prices[i-1];
        if (benefit>0)
            result += benefit;
    }
    return result;
}
因为买卖是时间线性的,直接贪心,大于0就算利润。


169Majority Element
public int majorityElement(int[] nums) {
    Arrays.sort(nums);
    return nums[nums.length/2];
}
排序,返回中位数。


217Contains Duplicate
public boolean containsDuplicate(int[] nums) {
    if (nums==null|| nums.length==0)
        return false;
    HashSet hs = new HashSet();
    for (int num: nums)
        if (hs.add(num)==false)
            return true;
    return false;
}
挨个扔HashSet里面,如果添加失败,返回true,如全部添加成功返回false。
268Missing Number
public int missingNumber(int[] nums) {
    int len = nums.length;
    int sum = (len*(len+1))/2;
    for(int i = 0 ; i < len; i++){
        sum -= nums[i];
    }
    return sum;
}
因为所有的数字都是连续且独一无二的,算一下他们的和,从头到尾挨个减一遍,剩下的值,就是缺省值。


287Find the Duplicate Number
public int findDuplicate(int[] nums) {
    int slow = 0;
    int fast = 0;
    do    {
        slow = nums[slow];
        fast = nums[nums[fast]];
    } while(slow != fast);
    int find = 0;
    while (find!=slow)
    {
        slow = nums[slow];
        find = nums[find];
    }
    return find;
}
迪杰斯特拉算法找环路

35Search Insert Position
public int searchInsert(int[] nums, int target) {
    if (nums==null||nums.length==0)
        return 0;
    int len = nums.length;
    int left = 0;
    int right = len-1;

    while (left <= right)
    {
        if (target < nums[left])
            return left;
        if (target > nums[right])
            return (right+1);
        int mid = (left + right)>>1;
        if (target < nums[mid])
            right = mid-1;
        else if (target > nums[mid])
            left = mid+1;
        else            return mid;
    }
    return 0;
}
二分查找,使用右移代替除2.

53Maximum Subarray

public int maxSubArray(int[] nums) {
    int max = nums[0];
    int[] sum = new int[nums.length];
    sum[0] = nums[0];
    for (int i = 1; i < nums.length; i++)
    {
        sum[i] = Math.max(nums[i], sum[i - 1] + nums[i]);
        max = Math.max(max, sum[i]);
    }

    return max;
}
动态规划,最优子结构result = max(nums[i],sum[i-1]+nums[i])