ネクタイネットワークアルゴリズム学習ノート-88
21747 ワード
ネクタイネットアルゴリズム学習ノート
このシリーズのアルゴリズムのテーマはネクタイネットから来ます
配列クラスアルゴリズム7日目
テーマ:88.2つの配列を結合
2つの整列整数配列*nums 1*とnums 2が与えられ、*nums 2*が*nums 1に結合され、*num 1*が整列配列になるようにします.
例:
説明:初期化nums 1およびnums 2の要素数は、それぞれmおよびnである. *nums 1*にはnums 2の要素を保存するのに十分な空間(空間サイズがm+n以上)があると仮定できます.
解題プロセス:
考え方一:
問題を見た最初の考えは、データを挿入してから、データを後ろに移動することですが、データを移動する代価が大きすぎて、その後は配列の長さで十分だと思って、直接後ろから置けばいいです.
コードは次のとおりです.
次のことを考えます.
実は书き终わって考えて、私はネストの循环を书く必要はないと思って、结局循环の回数は私は知っていて、そこで考えの2がありました.
考え方2:
サイクル数=m+n回、このようなサイクルを直接書けばよい.
コードは次のとおりです.
次のことを考えます.
これは主にいくつかの特殊な状況に注意しなければなりません.
ネクタイの上のこの問題の他の高品質の例:
自己整理:
ここでの考え方は,まず最大値を配列2に入れ,次に配列2の値を配列の後ろに置くことである.
この部分はそうは思わなかったが、私がこの問題をするときは数を挿入しようとしただけで、先にソートして挿入しようとは思わなかった.
方法が多く、複数の方位の思考が必要です.
このシリーズのアルゴリズムのテーマはネクタイネットから来ます
配列クラスアルゴリズム7日目
テーマ:88.2つの配列を結合
2つの整列整数配列*nums 1*とnums 2が与えられ、*nums 2*が*nums 1に結合され、*num 1*が整列配列になるようにします.
例:
:
nums1 = [1,2,3,0,0,0], m = 3
nums2 = [2,5,6], n = 3
: [1,2,2,3,5,6]
説明:
解題プロセス:
考え方一:
問題を見た最初の考えは、データを挿入してから、データを後ろに移動することですが、データを移動する代価が大きすぎて、その後は配列の長さで十分だと思って、直接後ろから置けばいいです.
コードは次のとおりです.
class Solution {
public void merge(int[] nums1, int m, int[] nums2, int n) {
// , ,
if((nums1.length == 1) && (nums1[0] == 0)){ // nums1
nums1[0] = nums2[0];
return;
}
int keynum = m+n-1; //
int arr1 = m-1;
for(int i = n-1;i>=0;i--){
for(;arr1>=0;arr1--){
if(nums2[i] >= nums1[arr1]){
nums1[keynum] = nums2[i];
keynum--;
break;
}else{
nums1[keynum] = nums1[arr1];
keynum--;
}
}
if(arr1<0){ // nums1 nums2 , nums2
nums1[keynum] = nums2[i]; // ,
keynum--;
}
}
}
}
// 5ms
次のことを考えます.
実は书き终わって考えて、私はネストの循环を书く必要はないと思って、结局循环の回数は私は知っていて、そこで考えの2がありました.
考え方2:
サイクル数=m+n回、このようなサイクルを直接書けばよい.
コードは次のとおりです.
class Solution {
public void merge(int[] nums1, int m, int[] nums2, int n) {
// , ,
if((nums1.length == 1) && (nums1[0] == 0)){
nums1[0] = nums2[0];
return;
}
int k = m+n-1;
for(;k>=0;k--){
if(m!=0 && n!=0){
if(nums1[m-1] < nums2[n-1]){
nums1[k] = nums2[n-1];
n--;
}else{
nums1[k] = nums1[m-1];
m--;
}
}else if(m==0){
nums1[k] = nums2[n-1];
n--;
}else if(n == 0){
nums1[k] = nums1[m-1];
m--;
}
}
}
}
//3ms
次のことを考えます.
これは主にいくつかの特殊な状況に注意しなければなりません.
1. , , ,
2. , ;
3. , 。
4. 2、3 , 。
ネクタイの上のこの問題の他の高品質の例:
class Solution {
public static void merge(int[] nums1, int m, int[] nums2, int n) {
// :
if(n==0) {
return;
}
int i = 0,j=0;
while(i<m) {
if(nums1[i]<=nums2[j]) {
i++;
}else {
swap(nums1,i++,nums2,j);
//
while(j+1<n&&nums2[j]>nums2[j+1]) {
swap(nums2, j,(j+1));
j++;
}
j = 0;
}
}
while(j<nums2.length) {
nums1[i++] = nums2[j++];
}
}
private static void swap(int[] nums2, int i, int j) {
// TODO Auto-generated method stub
nums2[i] = nums2[i]^nums2[j];
nums2[j] = nums2[i]^nums2[j];
nums2[i] = nums2[i]^nums2[j];
}
private static void swap(int[] nums1, int i, int[] nums2, int j) {
int temp = nums1[i];
nums1[i] = nums2[j];
nums2[j] = temp;
}
}
// 4ms
自己整理:
ここでの考え方は,まず最大値を配列2に入れ,次に配列2の値を配列の後ろに置くことである.
この部分はそうは思わなかったが、私がこの問題をするときは数を挿入しようとしただけで、先にソートして挿入しようとは思わなかった.
方法が多く、複数の方位の思考が必要です.