Back home

SENI #021

SENI #021

SENI adalah kegiatan yang diprakarsai oleh 由左耳朵耗子--陈皓: Kerjakan setidaknya satu pertanyaan algoritma leetcode setiap minggu, baca dan komentari setidaknya satu artikel teknis berbahasa Inggris, pelajari setidaknya satu keterampilan teknis, dan bagikan artikel yang berisi opini dan pemikiran. (Artinya, Algoritma, Review, Tip, dan Share disebut sebagai SENI) dan bertahan setidaknya selama satu tahun.

SENI 021

Ini adalah pasal 21

Pertanyaan algoritma algoritma

149. Poin Maks pada Satu Garis

Kesulitan Sulit

Diketahui n titik pada bidang 2D, tentukan jumlah maksimum titik yang terletak pada garis lurus yang sama.

Contoh 1:

Contoh 2:

Input: [[1,1],[2,2],[3,3]]
Output: 3
Explanation:
^
|
|        o
|     o
|  o  
+------------->
0  1  2  3  4
Input: [[1,1],[3,2],[5,3],[4,1],[2,3],[1,4]]
Output: 4
Explanation:
^
|
|  o
|     o        o
|        o
|  o        o
+------------------->
0  1  2  3  4  5  6

Solusi

Bahasa: C

/**
 * Definition for a point.
 * struct Point {
 *     int x;
 *     int y;
 * }
 */
int maxPoints(struct Point* points, int pointsSize) {
    
}

Pikiran pertama saya ketika melihat topik ini adalah menghitung kemiringan dan menggunakan angka ganda untuk menyatakan kemiringan. Implementasi pertama adalah sebagai berikut:


int maxPoints11(struct point* points, int pointsSize) {
    if (pointsSize == 0 || pointsSize == 1) {
        return pointsSize;
    }
    
    double* averageOfLevels = (double*)malloc(sizeof(double) * (pointsSize * (pointsSize -1) / 2));
    int index = 0;
    for (int i = 0; i< pointsSize; i++) {
        struct point pi =  points[i];
        
        for (int j = i+1; j< pointsSize; j++) {
            struct point pj =  points[j];
            
            double x = pi.x - pj.x;
            double y = pi.y - pj.y;
            
            if (x ==0) {
                averageOfLevels[index++] =INT_MAX;
            }
            else{
                averageOfLevels[index] = ((double)y)/x;
                index++;
            }
        }
    }

    
    //问题转换为数组中x最多相等的元素的个数
    //先排序 使用快排
    quicksort98(averageOfLevels, 0, index-1);
    int max = 0;
    int temp = 1;
    double pd ;
    double ld =  INT_MIN;

    for (int i = 0; i < index-1; i++) {
        pd = averageOfLevels[i];
        ld = averageOfLevels[i +1];
        if (pd == ld) {
            temp++;
        }else{
            if (temp > max) {
                max = temp;
            }
            temp=1;
        }
    }
    
    if (temp > max) {
        max = temp;
    }
    
    //分界位n*(n-1)
    int i = 1;
    for (;i*(i-1)/2 <=max ; i++) {
        if (i*(i-1)/2 ==max) {
            break;
        }
    }
    free(averageOfLevels);
    return i;
}


void quicksort98(double* a, int left, int right) {
    int i, j;
    double t, temp;
    if(left > right)
        return;
    temp = a[left]; //temp中存的就是基准数
    i = left;
    j = right;
    while(i != j) { //顺序很重要,要先从右边开始找
        while(a[j] >= temp && i < j)
            j--;
        while(a[i] <= temp && i < j)//再找右边的
            i++;
        if(i < j)//交换两个数在数组中的位置
        {
            t = a[i];
            a[i] = a[j];
            a[j] = t;
        }
    }
    //最终将基准数归位
    a[left] = a[i];
    a[i] = temp;
    quicksort98(a,left, i-1);//继续处理左边的,这里是一个递归的过程
    quicksort98(a,i+1, right);//继续处理右边的 ,这里是一个递归的过程
}

Implementasi di atas tidak dapat lolos jika kasus uji memiliki poin yang sama, karena situasi poin yang sama tidak dipertimbangkan. Cara di atas adalah menghitung kemiringan semua titik, kemudian mengurutkannya untuk mengetahui keadaan panjang lereng, kemudian menguraikan berapa kali kemiringan tersebut muncul untuk menghitung jumlah titik panjang.

Salah satu kelemahan dari ide implementasi ini adalah pertama-tama menghitung kemiringan semua titik dan kemudian melakukan penghitungan. Hal ini membuat lebih sulit untuk menangani titik duplikat.

Perbaikan pada metode ini adalah dengan menghitung kemiringan garis lurus antara setiap titik dengan titik lainnya, kemudian mencari titik yang paling optimal. Implementasinya adalah sebagai berikut:

int maxPoints(struct Point* points, int pointsSize){
    if (pointsSize == 0 || pointsSize == 1) {
        return pointsSize;
    }
    
    double* averageOfLevels = (double*)malloc(sizeof(double) * (pointsSize * (pointsSize -1) / 2));
    
    
    int max = 0;
    
    for (int i = 0; i< pointsSize; i++) {
        struct Point pi =  points[i];
        int smaple = 0;
        int index = 0;
        
        for (int j = 0; j< pointsSize; j++) {
            if (i==j) {
                continue;
            }
            struct Point pj =  points[j];
            
            double x = pi.x - pj.x;
            double y = pi.y - pj.y;
            
            if (x ==0) {
                if (y==0) {//同一个点
                    smaple++;
                }
                else{
                    averageOfLevels[index++] =INT_MAX;
                }
            }
            else{
                averageOfLevels[index] = ((double)y)/x;
                index++;
            }
        }
        
        
        
        
        quicksort98(averageOfLevels, 0, index-1);
        
        
        int temp = 1;
        int maxtemp = 0;
        double pd ;
        double ld =  INT_MIN;
        
        for (int i = 0; i < index-1; i++) {
            pd = averageOfLevels[i];
            ld = averageOfLevels[i +1];
            if (pd == ld) {
                temp++;
            }else{
                if (temp > maxtemp) {
                    maxtemp = temp;
                }
                temp=1;
            }
        }
        
        
        if (temp > maxtemp) {
            maxtemp = temp;
        }
        
        if (index >0) {
            maxtemp++;
        }
        
        
        
        
        maxtemp = maxtemp+ smaple;
        
        if ( maxtemp > max) {
            max = maxtemp;
        }
        
        free(averageOfLevels);
        averageOfLevels = (double*)malloc(sizeof(double) * (pointsSize * (pointsSize -1) / 2));
        
        
    }
    free(averageOfLevels);
    
    return max;
}


Implementasi di atas gagal ketika kasus uji [[0,0],[94911151,94911150],[94911152,94911151]], karena double mewakili kemiringan, dan kemiringan ketiga titik tersebut sama. Namun ketiga titik tersebut tidak berada pada satu garis lurus.

[[0,0],[94911151,94911150],[94911152,94911151]] Kasus uji ini seharusnya ditambahkan nanti. Beberapa kode bahasa C yang ditemukan di area komentar tidak dapat lulus uji kasus ini.

Kesulitan dari soal ini adalah bagaimana cara menyatakan kemiringan?

Belakangan, saya menemukan bahwa mengubah kemiringan yang dinyatakan dalam ganda menjadi ganda panjang dapat melewati semua kasus uji.

Faktanya, representasi ganda yang panjang bukanlah representasi perkiraan, dan mungkin ada beberapa tombol yang tidak dapat dilewati. Kemiringan pertanyaan ini harus dinyatakan dalam pecahan.

Kode lengkapnya adalah sebagai berikut:

void quicksort98(long double* a, int left, int right) {
    int i, j;
    long double t, temp;
    if(left > right)
        return;
    temp = a[left]; //temp中存的就是基准数
    i = left;
    j = right;
    while(i != j) { //顺序很重要,要先从右边开始找
        while(a[j] >= temp && i < j)
            j--;
        while(a[i] <= temp && i < j)//再找右边的
            i++;
        if(i < j)//交换两个数在数组中的位置
        {
            t = a[i];
            a[i] = a[j];
            a[j] = t;
        }
    }
    //最终将基准数归位
    a[left] = a[i];
    a[i] = temp;
    quicksort98(a,left, i-1);//继续处理左边的,这里是一个递归的过程
    quicksort98(a,i+1, right);//继续处理右边的 ,这里是一个递归的过程
}

int maxPoints(struct Point* points, int pointsSize){
    if (pointsSize == 0 || pointsSize == 1) {
        return pointsSize;
    }
    
    long double* averageOfLevels = (long double*)malloc(sizeof(long double) * (pointsSize * (pointsSize -1) / 2));
    
    
    int max = 0;
    
    for (int i = 0; i< pointsSize; i++) {
        struct Point pi =  points[i];
        int smaple = 0;
        int index = 0;
        
        for (int j = 0; j< pointsSize; j++) {
            if (i==j) {
                continue;
            }
            struct Point pj =  points[j];
            
            long double x = pi.x - pj.x;
            long double y = pi.y - pj.y;
            
            if (x ==0) {
                if (y==0) {//同一个点
                    smaple++;
                }
                else{
                    averageOfLevels[index++] =INT_MAX;
                }
            }
            else{
                averageOfLevels[index] = ((long double)y)/x;
                index++;
            }
        }
        
        quicksort98(averageOfLevels, 0, index-1);
        
        
        int temp = 1;
        int maxtemp = 0;
        long double pd ;
        long double ld =  INT_MIN;
        
        for (int i = 0; i < index-1; i++) {
            pd = averageOfLevels[i];
            ld = averageOfLevels[i +1];
            if (pd == ld) {
                temp++;
            }else{
                if (temp > maxtemp) {
                    maxtemp = temp;
                }
                temp=1;
            }
        }
        
        
        if (temp > maxtemp) {
            maxtemp = temp;
        }
        
        if (index >0) {
            maxtemp++;
        }
        
        maxtemp = maxtemp+ smaple;
        
        if ( maxtemp > max) {
            max = maxtemp;
        }

        free(averageOfLevels);
        averageOfLevels = (long double*)malloc(sizeof(long double) * (pointsSize * (pointsSize -1) / 2));
    }
    free(averageOfLevels);
    return max;
}

Ulasan

https://dandan2009.github.io/2018/12/28/exposing-NSDictionary/

TIPS

Ada banyak metode konfigurasi di situs konfigurasi Reveal, seperti ini: https://www.cnblogs.com/somethingWithiOS/p/6594496.html, Konfigurasinya merepotkan dan memerlukan perubahan file proyek. Berikut adalah metode sederhana.

Metode konfigurasi pod hanya satu baris tanpa mengubah file proyek:

pod ‘RevealServer’, :konfigurasi => [‘Debug’], :path => ‘./RevealServer’

:configurations berarti hanya valid dalam debug

       
 Pod::Spec.new do |s|

 s.name         = "RevealServer"
 s.version      = "15.3.3"
 s.summary      = "RevealServer sdk"

 s.description  = <<-DESC
                   RevealServer
                  DESC
 s.homepage     = "http://www.baidu.com"
 s.license      = "MIT"
 s.author             = { "zzz 2019-1-5" => "" }
 s.platform     = :ios, "7.0"  
 s.ios.deployment_target = "7.0"
 s.source       = { :git => "http://www.baidu.com" }
 s.source_files  = "RevealServer.framework/**/*.h"
 s.vendored_frameworks = 'RevealServer.framework'

end
  

Untuk demo selengkapnya, lihat: https://github.com/dandan2009/RevealServerDemo

Bagikan

Tidak cukup waktu, landasan lemah, algoritma pembelajaran non-teknis: 20110222559426