1、旋转数组的最小数字
题目描述
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素。 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。 NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
解法1:
注意旋转数组的特性:
- 1.包含两个有序序列
- 2.最小数一定位于第二个序列的开头
- 3.前序列的值都>=后序列的值(不一定)
- 定义把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。
- _这个旋转思想是很经典的
- 旋转数组实例:
- {123456}旋转后{456123}
public int minNumberInRotateArray1(int [] array) {
if(array!=null&&array.length>0){
if(array.length>1){
for (int i=1;i<array.length;i++) {
if(array[i]<array[i-1]){
return array[i];
}
}
}
return array[0];
}
return 0;
}
解法2:
//剑指offer
public int minNumberInRotateArray(int[] array) {
if (array.length == 0) {
return 0;
}
int left = 0;
int right = array.length - 1;
int mid = left;
while (array[left] >= array[right]) {
//循环结束的条件
if (right - left == 1) {
mid = right;
break;
}
mid = left + (right - left) / 2;
//1111011
if (array[left] == array[right] && array[left] == array[mid]) {
left++;
right--;
} else if (array[mid] >= array[left]) {
left = mid;
} else if (array[mid] <= array[right]) {
right = mid;
}
}
return array[mid];
}
2、81. 搜索旋转排序数组 II(头条)
3、189. 旋转数组
给定一个数组,将数组中的元素向右移动 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]
说明:
- 尽可能想出更多的解决方案,至少有三种不同的方法可以解决这个问题。
- 要求使用空间复杂度为 O(1) 的原地算法。
思路1: 时间复杂度:n*k;空间复杂度:1
public void rotate1(int[] nums, int k) {
if(nums.length==0||(k%nums.length)==0){
return;
}
int length=nums.length;
for (int i=0;i<k;i++){
int end=nums[length-1];
for (int j=length-2;j>=0;j--){
nums[j+1]=nums[j];
}
nums[0]=end;
}
}
思路2: 题目要求:空间复杂度为1,这个方法不满足要求
public void rotate2(int[] nums, int k) {
if(nums.length==0||(k%nums.length)==0){
return;
}
int length=nums.length;
int[] newNums=new int[length];
for (int i=0;i<length;i++){
newNums[(i+k)%length]=nums[i];
}
nums=newNums;
}
思路3: 先反转前length-k个数字,在反转后k个数字,然后把整个数组反转
例如:1234567 3–>4321 765–>567 1234
public void rotate(int[] nums, int k) {
if(nums.length==0||(k%nums.length)==0){
return;
}
k%=nums.length;
int length=nums.length;
reverse(nums,0,length-k-1);
reverse(nums,length-k,length-1);
reverse(nums,0,length-1);
}
private void reverse(int[] nums,int start,int end){
while (start<end){
int temp=nums[end];
nums[end--]=nums[start];
nums[start++]=temp;
}
}
4、左旋转字符串
题目描述
汇编语言中有一种移位指令叫做循环左移(ROL),现在有个简单的任务,就是用字符串模拟这个指令的运算结果。对于一个给定的字符序列S,请你把其循环左移K位后的序列输出。例如,字符序列S=”abcXYZdef”,要求输出循环左移3位后的结果,即“XYZdefabc”。是不是很简单?OK,搞定它!
思路:
先翻转前n个,后翻转后len-n个,最后全部翻转
public String LeftRotateString(String str,int n) {
if(str==null||str.equals("")||n%str.length()==0){
return str;
}
n%=str.length();
char[] chars=str.toCharArray();
reverseStr(chars,0,n-1);
reverseStr(chars,n,str.length()-1);
reverseStr(chars,0,str.length()-1);
return String.valueOf(chars);
}
private void reverseStr(char[] chars,int left,int right){
int i=left,j=right;
while(i<j){
char c=chars[i];
chars[i++]=chars[j];
chars[j--]=c;
}
}
5、翻转单词顺序列
题目描述
牛客最近来了一个新员工Fish,每天早晨总是会拿着一本英文杂志,写些句子在本子上。同事Cat对Fish写的内容颇感兴趣,有一天他向Fish借来翻看,但却读不懂它的意思。例如,“student. a am I”。后来才意识到,这家伙原来把句子单词的顺序翻转了,正确的句子应该是“I am a student.”。Cat对一一的翻转这些单词顺序可不在行,你能帮助他么?
思路:
先翻转整个字符串,然后翻转每个单词
public String ReverseSentence(String str) {
if(str==null||str.trim().equals("")){
return str;
}
char[] chars=str.toCharArray();
reverseChars(chars,0,chars.length-1);
int blank=-1;
for (int i=0;i<chars.length;i++){
if(chars[i]==' '){
reverseChars(chars,blank+1,i-1);
blank=i;
}
}
//最后一个单词单独进行反转
reverseChars(chars,blank+1,chars.length-1);
return new String(chars);
}
private void reverseChars(char[] chars, int start, int end) {
while (start<end){
char temp=chars[start];
chars[start]=chars[end];
chars[end]=temp;
start++;
end--;
}
}