1.题目: 数组跳跃
给定一个长度为N的非负的整数数组a[N],初始位置是数组的第一个位置,数组中的每一个数代表你至多能跳多远,如a[i]=3代表可以从a[i]调到a[i+3],判断你能否成功跳到数组的最后一个位置。输入为两行,第一行为数组的长度N,第二行为N个数,输出为0表示失败,1表示成功。
样例输入:
5
2 3 1 1 4
样例输出:
1
样例输入2:
5
3 2 1 0 4
输出:
0
public static int canJump(int n, int[] nums) {
int reach = 0; //记录i之前的最大跨越到达索引数
for (int i = 0; i < nums.length; i++) {
if (reach < i) { //跨不过这个0(i若为0,看i之前的最大跨越能否跨越i)
return 0;
}
if (i + nums[i] > reach) { //贪心记录
reach = i + nums[i];
}
}
return 1;
}
2.题目: 跳跃数组2
给定一个长度为N的非负的整数数组a[N],初始位置是数组的第一个位置,数组中的每一个数代表你至多能跳多远,如a[i]=3代表可以从a[i]调到a[i+3],你的目标是以最小的跳跃次数到达终点。输入为两行,第一行为数组的长度N,第二行为N个数,输出为跳跃次数。
样例输入
5
2 3 1 1 4
样例输出
2
(解释: 2->3->4,两次跳跃)
public static int canJump(int n, int[] nums) {
int reach = 0, lastJump = 0, count = 0; //lastJump记录上一跳 count记录最小跳数
for (int i = 0; i < nums.length; i++) {
if (reach < i) { //跨不过这个0(i若为0,看i之前的最大跨越能否跨越i)
return 0;
}
if (i > lastJump) { //i超越lastJump跳跃范围,再跳一次,赋值为reach(以判定能跨国这次i的最大)
count++;
lastJump = reach;
}
if (i + nums[i] > reach) { //贪心记录
reach = i + nums[i];
}
}
return 1;
}
动态规划(爬楼梯):
(选择 i 之前的能跳到 i 的所有位置j 中, dp[j] 值最小的位置 j 作为上一步要跳到 i 的位置)
class Solution {
public int jump(int[] nums) {
int[] dp = new int[nums.length];//dp[i] 为到达 i 位置的最小跳数
dp[0] = 0;//到达下标0的最小跳数是0
for (int i = 1; i < nums.length; i++) {
dp[i] = Integer.MAX_VALUE;
for (int j = 0; j < i; j++) {
if (j + nums[j] >= i) {
dp[i] = Math.min(dp[i], dp[j] + 1);
}
}
}
return dp[nums.length - 1];
}
}
3.题目: 完美平方数
给定正整数n,找到最小数量的完美平方数(例如1, 4, 9, 16, …),其总和为n。 例如,给定n = 12,返回3,因为12 = 4 + 4 + 4; 给定n = 13,返回2,因为13 = 4 + 9。
样例输入
12
样例输出
3
class Main {
public static int numSquares(int n) {
int[] dp = new int[n + 1];
Arrays.fill(dp, Integer.MAX_VALUE);
dp[0] = 0;
for(int i = 1; i <= n; ++i) {
int min = Integer.MAX_VALUE;
int j = 1;
while(i - j*j >= 0) {
min = Math.min(min, dp[i - j*j] + 1);
++j;
}
dp[i] = min;
}
return dp[n];
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int result = numSquares(n);
System.out.println(result);
}
}