java每日练习_day7(旋转数组的问题)

  1. 旋转数组
  2. 寻找旋转排序数组中的最小值
  3. 旋转字符串
  4. 旋转数字
  5. 旋转函数
  6. 搜索旋转排序数组_II
  7. 搜索旋转排序数组
  8. 搜索二维矩阵II
  9. 判断子序列
    1. 给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数。
    示例 1:
    输入: [1,2,3,4,5,6,7] 和 k = 3
    输出: [5,6,7,1,2,3,4]
    解释:
    向右旋转 1 步: [7,1,2,3,4,5,6]
    向右旋转 2 步: [6,7,1,2,3,4,5]
    向右旋转 3 步: [5,6,7,1,2,3,4]
    示例 2:
    输入: [-1,-100,3,99] 和 k = 2
    输出: [3,99,-1,-100]
    解释:
    向右旋转 1 步: [99,-1,-100,3]
    向右旋转 2 步: [3,99,-1,-100]
public static void rotate(int[] nums, int k) {
		int n = nums.length;
        k %= n;
        nums=swap(nums,0, n - 1);
        nums=swap(nums,0, k - 1);
        nums=swap(nums, k, n - 1);
    }
	private static int[] swap(int[] nums, int start, int end) {
		while (start < end) {
            int temp = nums[start];
            nums[start++] = nums[end];
            nums[end--] = temp;
        }
		return nums;
	}

2. 假设按照升序排序的数组在预先未知的某个点上进行了旋转。
( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。
请找出其中最小的元素。
你可以假设数组中不存在重复元素。
示例 1:
输入: [3,4,5,1,2]
输出: 1
示例 2:
输入: [4,5,6,7,0,1,2]
输出: 0

public static int findMin(int[] nums) {
		int start=0;
		int end=nums.length-1;
		//数组是有序的
		if(nums[end]>nums[start]) {
			return nums[start];
		}
		//数组是无序的
		int mid=0;
		while(start<end && end-start>1) {
			//mid=start+(end-start)/2;
			mid=(start+end)/2;
			if(nums[mid]>nums[start]) {
				start=mid;
			}else {
				end=mid;
			}
		}
		return Math.min(nums[start], nums[end]);
		
    }

3. 给定两个字符串, A 和 B。A 的旋转操作就是将 A 最左边的字符移动到最右边。 例如, 若 A = ‘abcde’,在移动一次之后结果就是’bcdea’ 。如果在若干次旋转操作之后,A 能变成B,那么返回True。
示例 1:
输入: A = ‘abcde’, B = ‘cdeab’
输出: true
示例 2:
输入: A = ‘abcde’, B = ‘abced’
输出: false

public class 旋转字符串 {
	public static void main(String[] args) {
		String A="abcde";
		String B="cdeab";
		rotateString(A,B);
	}
	public static boolean rotateString(String A, String B) {
		if(A.length()==B.length()) {
			return (A+A).contains(B);
		}else {
			return false;
		}        
    }
}

4. 我们称一个数 X 为好数, 如果它的每位数字逐个地被旋转 180 度后,我们仍可以得到一个有效的,且和 X 不同的数。要求每位数字都要被旋转。
如果一个数的每位数字被旋转以后仍然还是一个数字, 则这个数是有效的。0, 1, 和 8 被旋转后仍然是它们自己;
2 和 5 可以互相旋转成对方;6 和 9 同理,除了这些以外其他的数字旋转以后都不再是有效的数字。
现在我们有一个正整数 N, 计算从 1 到 N 中有多少个数 X 是好数?
示例:
输入: 10
输出: 4
解释:
在[1, 10]中有四个好数: 2, 5, 6, 9。
注意 1 和 10 不是好数, 因为他们在旋转之后不变。

public static int rotatedDigits(int N) {
		int count=0;
		for(int i=1;i<=N;i++) {
			boolean b=isGood(i);
			if(b) {
				count++;
			}
		}
		return count;
        
    }
	private static boolean isGood(int n) {
		boolean flag=false;
		//找到n的所有位
		while(n>0) {
			int ys=n%10;
			if(ys==3||ys==4||ys==7) {
				flag=false;
				break;
			}else if(ys==2||ys==5||ys==6||ys==9) {
				flag=true;
			}
			n=n/10;
		}
		if(flag) {
			return true;
		}else {
			return false;
		}	
	}

5. 给定一个长度为 n 的整数数组 A 。假设 Bk 是数组 A 顺时针旋转 k 个位置后的数组,我们定义 A 的“旋转函数” F 为:F(k) = 0 * Bk[0] + 1 * Bk[1] + … + (n-1) * Bk[n-1]。计算F(0), F(1), …, F(n-1)中的最大值。注意:可以认为 n 的值小于 105。
示例:
A = [4, 3, 2, 6]
F(0) = (0 * 4) + (1 * 3) + (2 * 2) + (3 * 6) = 0 + 3 + 4 + 18 = 25
F(1) = (0 * 6) + (1 * 4) + (2 * 3) + (3 * 2) = 0 + 4 + 6 + 6 = 16
F(2) = (0 * 2) + (1 * 6) + (2 * 4) + (3 * 3) = 0 + 6 + 8 + 9 = 23
F(3) = (0 * 3) + (1 * 2) + (2 * 6) + (3 * 4) = 0 + 2 + 12 + 12 = 26
所以 F(0), F(1), F(2), F(3) 中的最大值是 F(3) = 26 。

class Solution {
    public int maxRotateFunction(int[] A) {
        if(A==null || A.length==0) return 0;
        int sum = 0;
        int res = 0;
        int max = Integer.MIN_VALUE;
        int n = A.length;
        for (int i = 0; i < A.length; i++) {
            res += A[i] * i;
            sum += A[i];
        }

        for (int i = 0; i < A.length; i++) {
            res = res + n*A[i] - sum;
            max = Math.max(max, res);
        }
        return  max;
    }
}

6. 假设按照升序排序的数组在预先未知的某个点上进行了旋转。( 例如,数组 [0,0,1,2,2,5,6] 可能变为 [2,5,6,0,0,1,2] )。编写一个函数来判断给定的目标值是否存在于数组中。若存在返回 true,否则返回 false。
示例 1:
输入: nums = [2,5,6,0,0,1,2], target = 0
输出: true
示例 2:
输入: nums = [2,5,6,0,0,1,2], target = 3
输出: false
[1,1,3,1]
3

public static boolean search(int[] nums, int target) {
		return search(nums,0,nums.length-1,target);
	 }
	private static boolean search(int[] nums, int start, int end, int target) {
		if(start>end) {
			return false;
		}
		int mid=(start+end)/2;
		if(nums[mid]==target) {
			return true;
		}
		if(nums[mid]>nums[end]) {
			//前面是有序的
			if(nums[mid]>target && nums[start]<=target) {
				return search(nums,start,mid-1,target);
			}else {
				return search(nums,mid+1,end,target);
			}
		}else if(nums[mid]<nums[end]){
			//后面是有序的
			if(nums[mid]<target && nums[end]>=target) {
				return search(nums,mid+1,end,target);
			}else {
				return search(nums,start,mid-1,target);
			}
		}else {
			end--;
			return search(nums,start,end,target);
		}
	}

7. 假设按照升序排序的数组在预先未知的某个点上进行了旋转。( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。搜索一个给定的目标值,如果数组中存在这个目标值,则返回它的索引,否则返回 -1 。你可以假设数组中不存在重复的元素。你的算法时间复杂度必须是 O(log n) 级别。
示例 1:
输入: nums = [4,5,6,7,0,1,2], target = 0
输出: 4
示例 2:
输入: nums = [4,5,6,7,0,1,2], target = 3
输出: -1
[1,3]
3

public static int search(int[] nums, int target) {
		return search(nums,0,nums.length-1,target);
		
	}
	private static int search(int[] nums, int start, int end, int target) {
		if(start>end) {
			return -1;
		}
		int mid=(start+end)/2;
		if(nums[mid]==target) {
			return mid;
		}
		if(nums[mid]<nums[end]) {
			if(nums[mid]<target &&nums[end]>=target) {
				return search(nums,mid+1,end,target);
			}else {
				return search(nums,start,mid-1,target);
			}
		}else {
			if(nums[mid]>target && nums[start]<=target) {
				return search(nums,start,mid-1,target);
			}else {
				return search(nums,mid+1,end,target);
			}
		}
	}

8. 编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target。该矩阵具有以下特性:
每行的元素从左到右升序排列。每列的元素从上到下升序排列。
示例:
现有矩阵 matrix 如下:
[
[1, 4, 7, 11, 15],
[2, 5, 8, 12, 19],
[3, 6, 9, 16, 22],
[10, 13, 14, 17, 24],
[18, 21, 23, 26, 30]
]
给定 target = 5,返回 true。
给定 target = 20,返回 false。

 public static boolean searchMatrix(int[][] matrix, int target) {
		 //if(matrix == null || matrix.length == 0 || matrix[0].length == 0) return false;
		 if(matrix.length==0) {
			 return false;
		 }
		 int start=0;
		 int end=matrix[0].length-1;
		 while(start<matrix.length&&end>=0) {
			 if(matrix[start][end]==target) {
				 return true;
			 }else if(matrix[start][end]>target){
				 end--;
			 }else {
				 start++;
			 }
		 }
		return false;
	    }

9. 给定字符串 s 和 t ,判断 s 是否为 t 的子序列。你可以认为 s 和 t 中仅包含英文小写字母。字符串 t 可能会很长(长度 ~= 500,000),而 s 是个短字符串(长度 <=100)。字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。(例如,"ace"是"abcde"的一个子序列,而"aec"不是)。
示例 1:
s = “abc”, t = “ahbgdc”
返回 true.
示例 2:
s = “axc”, t = “ahbgdc”
返回 false.

 public static boolean isSubsequence(String s, String t) {
		 int index=-1;
		 for(int i=0;i<s.length();i++) {
			 index=t.indexOf(s.charAt(i),index+1);
			 if(index==-1) {
				 return false;
			 }
		 }
		 return true;     
	 }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值