2018-03-16 失败的刷题 AVL树

1067 Sort with Swap(0,*) 麻烦

题目很简单,给一个 [0, N)乱序的序列,n <= 10 ^ 5,只能用 0 和其它元素交换,问要交换多少次才能恢复升序。

想了想没有想到计算的办法,那就模拟吧。刚开始只存了这个序列,需要找元素的时候就得顺序查找,果然超时了。

改,又用了一个反向索引,记录每一个元素目前的位置。结果还有 case 超时。

后来终于不超时了。我放弃了之前“寻找还有没有不在其位的元素”的时候顺序查找的办法,而是用一个值记录还有多少个元素乱序。这里又折腾了半天,因为没想通,一般交换一次是有一个元素归位,但是当交换一个环,0恰好也归位时会多有一个元素归位;一个环结束后还得把 0 拿出来以启动下一次交换,这个操作会把本身在位置的 0 拉出来,乱序元素会增加 1。当乱序元素数为 0,就可以结束循环了。

不过把 0 拉出来跟任意一个乱序元素交换的时候,又涉及到顺序查找哪个元素是乱的。这里又用了一个数 wrong0 记录第一个乱序的元素,它每次都继续往后走,就不用从头循环了。

总之,当我去除了所有存在的顺序查找/遍历操作,就不超时了:-) 真是有毒的题。

丑唧唧的代码:

# include <cstdio>
# include <cstdlib>

int seq[100100];
int N;
int ans = 0;
int idx[100100]; //反向查找
int nWrong = 0;
int wrong0 = 1;

void swap(int n) { //0与n交换
    //printf("swap 0 and %3d: ", n);
    int idx0 = idx[0];
    seq[idx[n]] = 0; idx[0] = idx[n];
    seq[idx0] = n; idx[n] = idx0;
    ans++;
}

int main() {
    scanf("%d", &N);
    for (int i = 0; i < N; i++) {
        scanf("%d", seq + i);
        idx[seq[i]] = i;
        if (seq[i] != i) {
            nWrong++;
        }
    }

    int temp;
    while (nWrong > 0) {
        if (idx[0] == 0) {
            //找一个交换
            for (; wrong0 < N; wrong0++) {
                if (idx[wrong0] != wrong0) {
                    swap(seq[wrong0]);
                    nWrong ++;
                    break;
                }
            }
        }
        else {
            swap(idx[0]);
            nWrong--;
            if (idx[0] == 0) nWrong--;
        }
        /*for (int i = 0; i < N; i++) {
            printf("%d ", seq[i]);
        }printf("\n");
        for (int i = 0; i < N; i++) {
            printf("%d ", idx[i]);
        }printf("\n");
        printf("nWrong = %d\n", nWrong);*/
    }

    printf("%d", ans);

    return 0;
}

1066 Root of AVL Tree AVL树!

简单粗暴考你 AVL 树:给一个插入的序列,求最后树根是几。我佛佛佛。。。算了,认真写吧。在两眼一抹黑,也找不到之前写过的 AVL 树的情况下,凭着我奇葩的想象力,楞是从题目配图里找到了 AVL 树的规律。经过长时间的 debug (主要是处理不好 NULL 和 root 节点,到处报错)之后竟然通过了。。。通过了。。。

# include <cstdio>

#define max(a,b) ((a)>(b)? (a):(b))

struct node {
    int data;
    node *p, *lc, *rc;
};

node *root = NULL;
int N;

int hgt(node* pos) { //节点的高度,空树的高度为-1,单个节点的高度为0,有一个孩子的节点高度为1
    if (pos == NULL) return -1;
    return max(hgt(pos->lc), hgt(pos->rc)) + 1;
}

int balFac(node *pos) { //左孩子高度-右孩子高度
    int lh, rh;
    if (pos->lc == NULL) lh = -1; else lh = hgt(pos->lc);
    if (pos->rc == NULL) rh = -1; else rh = hgt(pos->rc);
    return lh - rh;
}

void insertAsRoot(int n) { //插入 root
    root = new node;
    root->data = n;
    root->lc = NULL;
    root->rc = NULL;
    root->p = NULL;
}

node *insertAsLc(node *pos, int n) { //插入到pos的左孩子
    node *newnode = new node;
    newnode->data = n;
    newnode->lc = NULL;
    newnode->rc = NULL;
    newnode->p = pos;
    pos->lc = newnode;
    return newnode;
}

node *insertAsRc(node *pos, int n) { //插入到pos的右孩子
    node *newnode = new node;
    newnode->data = n;
    newnode->lc = NULL;
    newnode->rc = NULL;
    newnode->p = pos;
    pos->rc = newnode;
    return newnode;
}

void leftRotate(node *pos) {
    node *b = pos->rc, *c = pos->rc->rc, *d = pos->rc->lc, *e = pos->lc;
    if (pos->p) {
        if (pos->p->lc == pos) { //是左孩子
            pos->p->lc = b;
        }
        else if (pos->p->rc == pos) { //是右孩子
            pos->p->rc = b;
        }
    }
    else {
        root = b;
    }
    b->p = pos->p;
    pos->rc = d; if (d) d->p = pos;
    b->lc = pos; pos->p = b;
}

void rightRotate(node *pos) {
    node *b = pos->lc, *c = pos->lc->lc, *d = pos->lc->rc, *e = pos->rc;
    if (pos->p) {
        if (pos->p->lc == pos) { //是左孩子
            pos->p->lc = b;
        }
        else if (pos->p->rc == pos) { //是右孩子
            pos->p->rc = b;
        }
    }
    else { //转的是root
        root = b;
    }
    b->p = pos->p;
    pos->lc = d; if(d) d->p = pos;
    pos->p = b; b->rc = pos;
}

void insert(int n) {
    if (root == NULL) { //空的
        insertAsRoot(n);
    }
    else { //树非空
        node *x = root, *prev = NULL;
        while (x) {
            if (n < x->data) {
                prev = x; x = x->lc;
            }
            else {
                prev = x; x = x->rc;
            }
        }
        if (n < prev->data) x = insertAsLc(prev, n); else x = insertAsRc(prev, n); //插入节点
        x = x->p->p; //爷爷可能开始不平衡
        while (x) { //找最先失衡的祖先
            if (balFac(x) >= 2 || balFac(x) <= -2) {
                if (balFac(x) == -2 && balFac(x->rc) == -1) {
                    leftRotate(x);
                }
                else if (balFac(x) == 2 && balFac(x->lc) == 1) {
                    rightRotate(x);
                }
                else if (balFac(x) == -2 && balFac(x->rc) == 1) {
                    rightRotate(x->rc);
                    leftRotate(x);
                }
                else if(balFac(x) == 2 && balFac(x->lc) == -1) {
                    leftRotate(x->lc);
                    rightRotate(x);
                }
                break;
            }
            x = x->p;
        }
    }
}

int main() {
    scanf("%d", &N);
    int t;
    for (int i = 0; i < N; i++) {
        scanf("%d", &t);
        insert(t);
    }

    printf("%d", root->data);

    return 0;
}
image.png

送自己一朵小 Fa Fa~

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,029评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,395评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,570评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,535评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,650评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,850评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,006评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,747评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,207评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,536评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,683评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,342评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,964评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,772评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,004评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,401评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,566评论 2 349

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,633评论 18 139
  • 国家电网公司企业标准(Q/GDW)- 面向对象的用电信息数据交换协议 - 报批稿:20170802 前言: 排版 ...
    庭说阅读 10,932评论 6 13
  • 我的未来在哪啊?
    70ea495b28aa阅读 314评论 0 1
  • 90天践行目标: 早睡早起:早6:00晚10:30 每周锻炼五次(跑步、健身、瑜伽) 每周阅读一本书,并写读书笔记...
    童小猫阅读 78评论 0 0
  • 我的家庭让我活得不像我,我只有努力个不停。
    LExiaoye阅读 128评论 0 0