117. 跳跃游戏 II

给出一个非负整数数组,你最初定位在数组的第一个位置。

数组中的每个元素代表你在那个位置可以跳跃的最大长度。   

你的目标是使用最少的跳跃次数到达数组的最后一个位置。

 

样例

给出数组A = [2,3,1,1,4],最少到达数组最后一个位置的跳跃次数是2(从数组下标0跳一步到数组下标1,然后跳3步到数组的最后一个位置,一共跳跃2次)

 

依旧是非常典型的动态规划问题,和http://www.cnblogs.com/TheLaughingMan/p/8154203.html类似,只不过这次用数组存储的是到达此位置需要跳跃的次数

 1 int jump(vector<int> &A) {
 2         // write your code here
 3         vector<int> minJump(A.size(), INT_MAX);
 4         minJump[0]=0;
 5         int leap, loc;
 6         for(int i=0;i<A.size();i++){
 7             leap=A[i];
 8             loc=i;
 9             while(leap&&loc<A.size()){
10                 leap--;
11                 loc++;
12                 minJump[loc]=min(minJump[i]+1, minJump[loc]);
13             }
14         }
15         return minJump[A.size()-1];
16     }

以上代码不是不能AC,间接性会有超时问题,触发的case如下

1,1999,1998,1997,1996,1995,1994,1993,1992,1991,1990,1989,1988,1987,1986,1985,1984,1983,1982,1981,1980,1979,1978,1977,1976,1975,1974,1973,1972,1971,1970,1969,1968,1967,1966,1965,1964,1963,1962,1961,1960,1959,1958,1957,1956,1955,1954,1953,1952,1951,1950,1949,1948,1947,1946,1945,1944,1943,1942,1941,1940,1939,1938,1937,1936,1935,1934,1933,1932,1931,1930,1929,1928,1927,1926,1925,1924,1923,1922,1921,1920,1919,1918,1917,1916,1915,1914,1913,1912,1911,1910,1909,1908,1907,1906,1905,1904,1903,1902,1901,1900,1899,1898,1897,1896,1895,1894,1893,1892,1891,1890,1889,1888,1887,1886,1885,1884,1883,1882,1881,1880,1879,1878,1877,1876,1875,1874,1873,1872,1871,1870,1869,1868,1867,1866,1865,1864,1863,1862,1861,1860,1859,1858,1857,1856,1855,1854,1853,1852,1851,1850,1849,1848,1847,1846,1845,1844,1843,1842,1841,1840,1839,1838,1837,1836,1835,1834,1833,1832,1831,1830,1829,1828,1827,1826,1825,1824,1823,1822,1821,1820,1819,1818,1817,1816,1815,1814,1813,1812,1811,1810,1809,1808,1807,1806,1805,1804,1803,1802,1801,1800,1799,1798,1797,1796,1 

注意到这是一个以1开头,然后从1999倒数的一个case,在实际运行中,存储跳跃次数的数组中的大部分元素会被重复更新多次。

那么我们优化的思路就是减少这种无意义的更新

 1     int jump(vector<int> &A) {
 2         // write your code here
 3         vector<int> minJump(A.size(), INT_MAX);
 4         minJump[0]=0;
 5         int leap, loc;
 6         for(int i=0;i<A.size();i++){
 7             leap=A[i];
 8             loc=i;
 9             while(leap&&loc<A.size()){
10                 leap--;
11                 loc++;
12                 minJump[loc]=min(minJump[i]+1, minJump[loc]);
13                 if(loc==A.size()-1){
14                     return minJump[loc];
15                 }
16             }
17         }
18         return minJump[A.size()-1];
19     }

这个代码在原先的思路上,加上了“只要是能第一个跳到最后一个的,就返回对应结果”,这样不管后面的位置能不能跳到最后一个都不更新了,所以存储跳跃次数的数组最后一个只更新一次,并将这个结果返回。

在第一个能AC的情况下对比运行时间,优化过的代码效率高上了很多

posted @ 2018-01-02 15:06  三人木君  阅读(514)  评论(0编辑  收藏  举报