【leetcode】solution in java——Easy2

转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6410409.html

6:Reverse String

Write a function that takes a string as input and returns the string reversed.

此题:字符串反转题。

思路:此题大一学C++的时候上机题就做过了,当时思路是:把String转化为char[],从尾到头遍历一次倒序地把字符复制到另一个数组(从头到尾),然后把新数组toString()即可。现在用Java做的话,把新数组换成用StringBuffer代替,倒序遍历char[]逐个append到buffer,然后toString()即可。由于每个元素都遍历了一次,复杂度O(n)。

 public String reverseString(String s) {
        char[] chars=s.toCharArray();
        StringBuffer buffer=new StringBuffer();      
        for(int i=chars.length-1;i>=0;--i){
            buffer.append(chars[i]);
        }        
        return buffer.toString();
    }

第二种思路是:把char[]的前后半交换即可,只需遍历一半,复杂度O(n/2)。

 public String reverseString(String s) {
        char[] chars=s.toCharArray();
        int half=chars.length/2;
        for(int i=0;i<half;++i){
            char temp=chars[chars.length-1-i];
            chars[chars.length-1-i]=chars[i];
            chars[i]=temp;
        } 
        //这里注意:char[]转化为String是通过new String(char[])实现的
        return new String(chars);
    }

 7:Island Perimeter

You are given a map in form of a two-dimensional integer grid where 1 represents land and 0 represents water. Grid cells are connected horizontally/vertically (not diagonally). The grid is completely surrounded by water, and there is exactly one island (i.e., one or more connected land cells). The island doesn't have "lakes" (water inside that isn't connected to the water around the island). One cell is a square with side length 1. The grid is rectangular, width and height don't exceed 100. Determine the perimeter of the island.

此题:输入一个二维矩阵表示地图,1表示陆地0表示水。岛屿是有1组成的四连通的图且只有一个岛屿。每个方格边长为1。求岛屿周长。

思路:此题的关键在于,相邻的1所处的方格边有重叠,周长只算外围的边。仔细观察每个1所处方格对周长的贡献,可以发现,有1相邻的那条边是不算入岛屿周长的。由此可得解题思路:遍历整个二维矩阵,每当遇到1,则count_1++(统计1的数目),然后对这个1进行上下左右试探,若有1相邻,则减去1条边,minus++(这条边对周长没贡献)。最后,由4*count_1得出所有1总共的边长,再减去对周长没贡献的边minus数,即得岛屿周长。

public int islandPerimeter(int[][] grid) {
       int res=0;
       int count_1=0;
       int minus=0;
       for(int i=0;i<grid.length;++i){
           for(int j=0;j<grid[0].length;++j){
               if(grid[i][j]==1){
                   count_1++;
                   //
                   if(i-1>=0 && grid[i-1][j]==1){
                       minus++;
                   }
                   //
                   if(j+1<grid[0].length && grid[i][j+1]==1){
                       minus++;
                   }
                   //
                   if(i+1<grid.length && grid[i+1][j]==1){
                       minus++;
                   }
                   //
                   if(j-1>=0 && grid[i][j-1]==1){
                       minus++;
                   }
               }
           }
       }
       res=4*count_1-minus;       
       return res; 
    }

 8:Max Consecutive Ones

Given a binary array, find the maximum number of consecutive 1s in this array.

此题:给出一个元素只含1、0的数组,统计最长的连续1串的长度。

思路:用一个temp值保存当前最长的1连续串的长度。从头开始遍历数组,遇1则count++,然后比较当前count与temp,temp取大值。时刻更新temp,最后把temp返回。

这里有个坑:如果是遇0才把count与temp比较取大,然后count=0统计下一个连续的1串,这样的话不是时刻更新temp,若最长的连续1串一直延续到数组末尾。则temp是没机会更新的。

public int findMaxConsecutiveOnes(int[] nums) {
            int temp=0;
            int count=0;
            for(int i:nums){
                count = i==1?++count:0;
                temp=Math.max(temp, count);                
            }
            return temp;
        }

 9:Nim Game

You are playing the following Nim Game with your friend: There is a heap of stones on the table, each time one of you take turns to remove 1 to 3 stones. The one who removes the last stone will be the winner. You will take the first turn to remove the stones.

Both of you are very clever and have optimal strategies for the game. Write a function to determine whether you can win the game given the number of stones in the heap.

此题:博弈论的题。两人轮流取石头,每次1~3块,取到最后一块的算赢。你先取,问在n块石头的情况下你能不能赢?

通用的解题思路是:对于一堆n块的石头,每次能取1~m块。如果n=m+1,那么先取的无论怎么取,剩下的都<=m,后取的赢。由此可得,我们要做的就是,争取制造出这样的一种结果:在最后一次取时,刚好是m+1块给对方取,那么我们随后就可以一次取完。怎么达到呢?由于我们是先手,由n=(m+1)*r+s得出这堆石头是m+1的多少倍余多少块,然后我们先取走s块,则留下(m+1)*r块石头。此时,开启我们的交锋——每个回合都是他先取,而且面对的都是m+1的倍数。他无论怎么取(假如取k块),我们只需取走(m+1-k)块即可保持剩余石头数仍是m+1的倍数(即保持每个回合两人总共取走m+1个)......直到最后一个回合开始时,刚好剩下m+1块而且是他先手,那么他无论怎么取,我们都可以随后一次取完。则把问题转变为了求:n<=m||n=(m+1)*r+s(0<s<=m)这条式子是否成立,成立则我们赢,否则对手赢。(由此也可得博弈论类题目,都不是单纯的模拟推演结果,因为每个回合变数太大不可能推演完全的。而博弈是个零和游戏,总会有输赢,我们要做的就是找出必胜的情况,得出必胜的公式,然后由公式成立与否得结果

 public boolean canWinNim(int n) {
       //注意边界:n<=m,先手的一次取完就赢了。而(m+1)*r+s(0<s<=m)不是为了求r,而是为了确保s不为0,使我们先手时能取s,否则就是对方利用这条公式对付我们了
       //如果进一步,最快取多少次后获胜,则我们还要把r求出来。
       if(n<=3||n%4!=0){
           return true;
       }
       return false;
    }

 10:Find All Numbers Disappeared in an Array

Given an array of integers where 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice and others appear once.

Find all the elements of [1, n] inclusive that do not appear in this array.

Could you do it without extra space and in O(n) runtime? You may assume the returned list does not count as extra space.

此题:给出一个n长数组,每个元素在1~n之间,且元素可以重复出现。求1~n这n个整数哪个不在数组中。

思路:这道题有性能限制,O(n)以内,所以不能用普通的嵌套循环来做的。由前面的题目的灵感,这种找位置(下标)类情况,绝对要用map啦!先遍历一次数组,每个元素作为key又作自身的value存入map。然后再遍历1~n这n个数字,由map.get(i)得不到value的说明不在数组中,list.add(i)。最后返回list即可。

public List<Integer> findDisappearedNumbers(int[] nums) {
        List<Integer> list=new ArrayList<Integer>();
        Map<Integer, Integer> map=new HashMap<Integer, Integer>();
        for(int i:nums){
            map.put(i, i);
        }
        for(int i=1;i<=nums.length;++i){
            if(map.get(i)==null){
                list.add(i);
            }
        }
        return list;
    }
原文地址:https://www.cnblogs.com/ygj0930/p/6410409.html