Word List 1

词根词缀预习表

词根/词缀 含义 例词及释义
act exact adj. 精确的;准确的
reg 国王 regent n. 摄政者
philo philosophy n. 哲学;哲理
chron 时间 chronic adj. (疾病) 慢性的
vari 变化 variety n. 品种;变化
equi 相等 equity n. 公平,公正
cav excavate v. 挖掘,开凿
mut 改变 mutual adj. 相互的;共同的
pan 面包 companion n. 共事者;同伴
vas invasion n. 入侵,侵略
  • delve [delv] v. 钻研;探索,探究
    • 联想记忆:埋在书架 (shelves) 里整天钻研 (delve)
    • 例句:Thomas Hardy is delving into matters we all recognise because they are common to humanity. 托马斯·哈代正在探究的是我们都能辨识的事物,因为它们是人类所共有的。
  • exact [ig’zækt] adj. 精确的;准确的
    • 词根记忆:ex (出) + act (做) → 做出精确的结果 → 精确的;准确的
    • 例句:What is the exact amount left in your savings account? 你储蓄账户上的准确余额是多少?
    • 拓展:exactly (adv. 正确地;完全地)
  • elicit [I’lIsIt] v. 引出,诱出
    • 词根记忆:e (出) + lic (诱骗) + it → 诱骗到外面来 → 诱出,引出
    • 例句:elicit no response 没有得到回应
    • 例句:The students then were randomly assigned to watch a video clip eliciting either humour, contentment, or neutral feelings. 然后,学生们被随机分配观看一段视频,这些视频要么激发幽默感、满足感,要么不激发情感变化。
  • traditional [tra’dısənl] adj. 传统的,惯例的;口传的,传说的
    • 常见搭配:traditional view 传统观点; traditional belief 传统信条; traditional industry 传统工业; traditional method 传统方法
    • 例句:Rosewood is a pure example of a traditional country house of this part of England. 红木建筑是英格兰这个地区传统乡间住宅的一个典型代表。
  • lack [læk] n./v. 缺乏,不足,没有
    • 常见搭配:lack of 缺乏,没有; lack (for) nothing 什么都不缺
    • 例句:Martin can’t afford the book due to lack of money. 由于缺钱,马丁买不起这本书。
  • regent [ ‘ri:dzənt ] n. 摄政者 (代国王统治者)
    • 词根记忆:reg (国王) + ent (表人) → 摄政者
    • 例句:George acted as a regent when the present king was a child. 当现任国王还是孩子时,乔治担任摄政王。
  • burgeon [ ‘b3:dzən ] vi. 迅速成长;发展
    • 词根记忆:burg (=bud, 花蕾) + eon → 像花蕾一样成长 → 迅速成长
    • 例句:To serve the burgeoning tourist industry, an array of professionals has emerged. 为了满足日益繁荣的旅游业的发展需求,一大批专业人员已经出现了。
  • argue [ ‘a:gju: ] v. 争论;说服
    • 发音记忆:“阿Q” → 阿Q喜欢和人争论 → 争论
    • 常见搭配:argue sb. into/out of doing 说服某人做/不做某事;argue for 赞成,要求;argue about 议论……;argue over 辩论/争论……
    • 例句:The study argues that the type of action needed against passive smoking should be similar to that being taken against other diseases. 该研究认为人们需要采取类似防范其他疾病的行动来防范被动吸烟。
    • 拓展:arguably (adv. 可论证地,可辩解地)
  • barely [ ‘beǝli ] adv. 仅仅,几乎不;赤裸裸地,无遮蔽地
    • 例句:Rainfall barely penetrates the soil in this area. 在该地区,降雨很少渗入土壤。
      hierarchy [ ‘haiǝra:ki ] n. 领导层;层次,等级
    • 例句:It is likely that all uniforms make symbolic sense, namely, denoting a hierarchy. 很可能所有的制服都具有象征意义,即体现了穿衣人的等级。
  • guidance [ ‘gaıdns ] n. 指引,指导
    • 联想记忆:guid(e) (指引,指导) + ance (表名词) → 指引,指导
    • 常见搭配:guidance system 向导系统;moral guidance 精神指导
    • 例句:We will solicit guidance and aid from legal experts. 我们将向法律专家寻求指导和帮助。
  • easy-going [ ,i:zi ‘gǝvin ] adj. 脾气随和的,心平气和的;随便的**
    • 例句:The interviews don’t tell you if applicants are easy-going or hate smoking or whatever. 从面试中你看不出求职者是否随和或者讨厌吸烟之类的。
  • electrical [ I’lektrikl ] adj. 电的;电学的;有关电的
    • 常见搭配:electrical fault 电气故障
    • 例句:The small battery-powered gadget can deliver subliminal electrical pulses to the skin. 这种小的电池驱动装置可以向皮肤传达微小的电脉冲。
    • 拓展:electrically (adv. 电力地)
  • electronic [ ,lek’tronik ] adj. 电子的
    • 来自 electric (adj. 电的)
    • 例句:Computers make up of the so-called electronic media. 所谓的电子媒介是由计算机构成的。
  • philosophy [fə’lɒsəfi] n. 哲学;哲理
    • 词根记忆:philo (爱) + soph (智慧) + y (表名词) → 爱智慧的学问 → 哲学;哲理
    • 例句:Try your best to succeed – that’s my philosophy. 竭尽全力,取得成功——这就是我的人生哲学。
    • 拓展:philosopher (n. 哲学家,哲人)
  • chronic [ ‘krɒnɪk ] adj. (疾病) 慢性的;积习难改的
    • 词根记忆:chron (时间) + ic (……的) → 长时间的 → (疾病) 慢性的
    • 常见搭配:chronic problem 长期的问题;chronic smoker 积习难改的烟民;chronic disease 慢性疾病;chronic war 持久战
    • 例句:Jim suffers from chronic back pain after the car-wreck. 车祸后吉姆一直受背痛的折磨。
    • 拓展:inveterate (adj. 根深蒂固的;成癖的)
  • desirable [dɪ’zaɪərəbl] adj. 值得拥有的;合意的;可取的,有利的
    • 来自 desire (v. 渴望)
    • 例句:Selecting the right person for the job involves more than identifying the essential or desirable range of skills. 为一份工作选择合适的人选,不能只看此人是否拥有胜任这份工作的基本技能和相应专长。
  • consortium [kən’sɔ:tiəm] n. 集团;财团;社团,协会
    • 联想记忆:consort (陪伴,结交) + ium → 结交组成团体 → 社团,协会
    • 例句:The consortium that won the contract for the island opted for an aggressive approach. 赢得这座岛屿 (开发) 合同的财团采取了一种野蛮的开发方式。
  • buckle [ ‘bʌkl ] v. 扣紧;(使) 变形;弯曲 n. 皮带扣环
    • 联想记忆:扣紧 (buckle) 雄鹿 (buck),防止挣脱
    • 例句:Buildings, pipes and roads tend to buckle and crack because of the movement of the earth. 由于地壳的运动,建筑物、地下管道以及道路等往往会变形甚至破裂。
  • curry [ ‘kʌri ] n. 咖喱;咖喱饭菜 vt. 把 (肉、蔬菜等) 做成咖喱食品;梳刷 (马毛等)
    • 常见搭配:curry powder 咖喱粉
    • 例句:Which kind of curry do you like, mild or peppery? 你喜欢哪种咖喱,微辣的还是辛辣的?
  • subliminal [sʌb’lɪmɪnl] adj. 下意识的;潜意识的
    • 词根记忆:sub (下) + limin (=limen,最小限度的神经刺激) + al (……的) → 下意识的,潜意识的
    • 例句:How we look sends all sorts of subliminal messages to other people. 我们的外表向其他人传达了各种潜在的信息。
    • 拓展:subliminally (adv. 下意识地,潜意识地)
  • chamber [ ‘tʃeɪmbə(r) ] n. 室;洞穴;(枪) 膛
    • 例句:In the brood chamber below, the bees will stash honey to eat later. 在蜂巢的下部,蜜蜂会贮藏蜂蜜,以供日后食用。
  • frequent [ ‘fri:kwənt ] adj. 频繁的;常见的;常用的
    • 词根记忆:frequ (频繁,频率) + ent (具有……性质的) → 频繁的;常见的
    • 例句:Frequent failures did not affect his morale. 屡屡失败并未让他泄气。
    • 拓展:frequently (adv. 常常,频繁地)
  • prosperous [ ‘prɒspərəs ] adj. 繁荣的,兴旺的;成功的
    • 例句:a prosperous city 一座繁华的都市
    • 例句:My grandfather once was a prosperous Britain businessman. 我祖父曾是一名成功的英国商人。
  • purpose [ ‘p3:pəs ] n. 目的,意图;用途,效果 v. 打算,企图;决心
    • 常见搭配:on purpose 故意地,有意地;with the purpose of 为了;statement of purpose 目的陈述
    • 例句:Bob was absent from school on purpose. 鲍勃故意逃学了。
  • variety [ və’raɪəti ] n. 品种,种类;变化,多样化
    • 词根记忆:vari (变化) + ety (表状态) → 有很多变化 → 品种;变化
    • 常见搭配:a variety of 许多
    • 例句:The places we will visit offer a variety of shopping. 我们将参观的地方可提供各种购物活动。
  • immigration [ ,ɪmɪ’greɪʃn ] n. 外来的移民;移居 (入境)
    • 词根记忆:im (向内) + migr (迁移) + ation (表行为) → 向内迁移 → 移居 (入境)
    • 常见搭配:immigration law 移民法;immigration controls 移民管制;immigration application 移民申请
    • 例句:There will be stricter controls on immigration into the country. 以后要移民到这个国家会面临更严格的管制。
  • natural [ ‘nætʃrəl ] adj. 正常的;普通的;自然的;自然界的,天然的;天赋的;固有的
    • 常见搭配:natural disaster 自然灾害;natural scenery 自然景观
    • 例句:It’s natural for an old man of his age to be so calm. 处于他这般年纪的老人如此镇静是很自然的。
  • bet [ bet ] v. 赌,打赌 n. 打赌,赌注
    • 常见搭配:bet on 打赌;赌博;bet with sb. 和……打赌
    • 例句:Anyway I bet there are some things you didn’t know about bananas. 不管怎样,我敢说对于香蕉,你肯定有不知道的地方。
  • consumer [ kən’sju:mə(r) ] n. 消费者;用户
    • 例句:Many consumers feel that government and business have taken on the environmental agenda. 许多消费者认为政府和商家已经将环保提上了日程。
    • 拓展:consumerism (n. 消费主义)
  • physician [ fɪ’zɪʃn ] n. 内科医生,医师
    • 词根记忆:physic (医学) + ian (表人) → 医师
    • 例句:The physician said smoking was harmful to my health. 那位医生说吸烟对我的健康有害。
  • equal [ ‘i:kwəl ] adj. 相等的;能胜任的 vt. 比得上
    • 例句:These four firms had equal levels of productivity. 这四家公司的生产力水平不相上下。
    • 拓展:equality (n. 同等,平等);equally (adv. 平等地,相等地)
  • resort [ ri’zɔ:t ] n. 求助;诉诸;(度假)胜地 vi. 求助;诉诸
    • 联想记忆:报告(report)上级,紧急求助(resort)
    • 例句:The east coast resorts are only a short twenty-minute drive from here. 从这儿开车去东海岸的度假胜地只需短短20分钟。
  • leadership [ ‘li:dəʃɪp ] n. 领导;领导层;领导能力
    • 联想记忆:leader (领导者) + ship (表身份) → 领导,领导层
    • 例句:Last week we talked about the most effective ways of leading meetings, and the advantages and disadvantages of different leadership styles. 上周,我们讨论了主持会议最有效的方法以及不同主持风格的利弊。
  • equity [ ‘ekwəti ] n. 公平,公正
    • 词根记忆:equi (相等) + ty (表状态) → 等价交换 → 公平,公正
    • 例句:The equity of the committee’s decision was accepted by everyone. 委员会所做决定的公正性得到了大家的一致认可。
  • excavate [ ‘ekskəveɪt ] v. 挖掘,开凿;(科学家或考古学家)发掘,挖出(古物等)
    • 词根记忆:ex (出) + cav (洞) + ate (使…) → 挖出洞 → 挖掘,开凿
    • 例句:Some large species of dung beetles originating from France excavate tunnels to a depth of approximately 30 cm below the dung pat. 一些源自法国的大型蜣螂品种会在粪堆下挖一条大约30厘米深的隧道。
  • nuclear [ ‘nju:kliə(r) ] adj. 核能的,原子能的
    • 联想记忆:nu + clear (清除) → 清除核危机 → 核能的
    • 例句:France derives three quarters of its electricity from nuclear power. 法国四分之三的电来自核能。
  • mutual [ ‘mju:tʃuəl ] adj. 相互的;共同的
    • 词根记忆:mut (改变) + ual (有…性质的) → 穷则思变,共同发展 → 相互的;共同的
    • 常见搭配:mutual understanding 相互理解;the principle of equality and mutual benefit 平等互惠的原则
    • 例句:They soon discovered a mutual interest in music. 很快,他们发现他们对音乐有着共同的兴趣。
  • density [ ‘densəti ] n. 密集;浓度,密度
    • 常见搭配:population density 人口密度;the density of settlement 居住密度
    • 例句:The house has some high-density insulation materials in the roof. 房子的屋顶采用了一些高密度的绝缘材料。
  • massive [ ‘mæsɪv ] adj. 大而重的,厚实的,粗大的;大量的,大规模的
    • 例句:In Tokyo builders are planning a massive underground city to be begun in the next decade. 在东京,建筑者们正计划在接下来的十年里建造一个大型地下城。
  • congratulate [kən’grætʃəleɪt] vt. 祝贺
    • 词根记忆:con (共同) + grat (令人高兴的) + ulate → 同喜同贺 → 祝贺
    • 例句:I wanted to congratulate you all on having passed the exam. 大家都通过了考试,我向你们表示祝贺。
  • companion [kəm’pænjən] n. 共事者;同伴,伙伴
    • 词根记忆:com (共同) + pan (面包) + ion → 共享面包的人 → 共事者;同伴,伙伴
    • 例句:Tom was my only Chinese companion during my stay in Switzerland. 汤姆是我在瑞士期间唯一的中国伙伴。
  • rig [rɪg] vt. 操纵、垄断 n. 船桅 (或船帆等) 的装置;成套器械
    • 联想记忆:挖 (dig) 个洞把器械 (rig) 藏起来
    • 例句:The defeated candidate claimed that the election was rigged. 落选的候选者称选举被人操纵了。
  • input [‘ɪnpʊt] n. 投入,输入;输入的数据 vt. 把……输入计算机
    • 来自词组 put in (投入;输入)
    • 例句:The intensity of farming in the rich world should decline, and the use of chemical inputs will diminish. 富裕国家应该降低农业生产的密度,这样化学药品的使用将会减少。
  • merely [‘mɪəlɪ] adv. 仅仅,只不过
    • 例句:You don’t have to be present. Merely send a letter of explanation. 你不一定非出席不可,只要寄封信去说明一下就可以了。// I meant it merely as a joke. 我只不过是开个玩笑。
      impart [ɪm’pɑ:t] vt. 给予,赋予;传授;告知,透露
    • 常见搭配:impart knowledge 传授知识
    • 例句:He told me not to impart it to anyone without his own permission. 他告诉我,未经他人允许不可以把此事透露给任何人。
  • forfeit [‘fɔ:fɪt] v. (因犯规等而) 丧失,失去 n. 罚款;代价
    • 联想记忆:for (因为) + feit (看作词根 fect,做) → 因为做错事,所以被处罚 → 罚款
    • 例句:He forfeited his driving licence because he drove after drinking. 他因酒后驾车被没收了驾照。
  • counteract [ˌkaʊntər’ækt] v. 抵消;对抗;中和
    • 联想记忆:counter (相反) + act (动作) → 做相反的动作 → 抵消
    • 例句:Antacid will counteract the excess acid in your stomach. 解酸剂会中和胃里剩余的酸。
  • ventilation [ˌventɪ’leɪʃn] n. 空气流通;通风设备,通风方法
    • 来自 ventilate (vt. 使通风)
    • 例句:rooms with good ventilation 通风良好的房间;ventilation system 通风系统
    • 例句:In the noisiest areas mechanical ventilation will have to be installed in the exterior walls. 在噪音最大的区域,必须在外墙安装机械通风设备。
  • intermediate [ˌɪntɜː’miːdiət] adj. 中间的,中级的 n. 中间物
    • 词根记忆:inter (在……之间) + medi (中间) + ate (具有……的) → 中间的
    • 例句:Students who have reached an intermediate level benefit from learning general English skills. 那些英语水平达到中级的学生从英语综合技能学习中受益匪浅。
  • eternal [ɪ’tɜːnl] adj. 永恒的
    • 联想记忆:外部 (external) 世界是永恒的 (eternal) 诱惑
    • 例句:The supersession of the old by the new is a general, eternal and inviolable law of the universe. 新旧更迭是宇宙间普遍的、永恒的、不可违背的规律。
    • 拓展:endless (adj. 无止境的);everlasting (adj. 永恒的,持久的);permanent (adj. 永久的,持久的)
    • 反义词:momentary (adj. 瞬间的,刹那的);temporary (adj. 暂时的)
  • invasion [ɪn’veɪʒn] n. 入侵,侵略
    • 词根记忆:in (进入) + vas (走) + ion (表动作) → 走进来 → 入侵,侵略
    • 例句:The freedom from foreign invasion enables a country to develop its natural resources steadily. 不受外来侵略可以使一国的自然资源得到稳定的开发。
  • nevertheless [ˌnevədə’les] adv. 尽管如此;然而,不过
    • 例句:He was tired. Nevertheless he kept on working. 他累了,不过他仍然继续工作。
      celebrate* [‘selɪbreɪt] v. 赞扬,歌颂;庆祝
    • 例句:The architectural style celebrated scientific and engineering achievements by openly parading the sophisticated techniques used in construction. 该建筑风格通过公开展示建筑中使用 的先进技术来歌颂科学和工程方面的成就。
    • 拓展:celebration (n. 庆祝,庆典)
  • inspiring [ɪn’spaɪərɪŋ] adj. 鼓舞 (或激励) 人心的;启发灵感的
    • 词根记忆:in (使……) + spir (呼吸) + ing (令人……的) → 使呼吸的 → 鼓舞人心的
    • 例句:an inspiring story 一个激励人心的故事
    • 例句:King was an inspiring tutor. 金是一位激励人心的导师。
  • attendance [ə’tendəns] n. 到场,出席;出勤;伺候,照料
    • 来自 attend (v. 出席;照顾,护理)
    • 常见搭配:take attendance 点名;attendance record 考勤记录
    • 例句:I do not think there is a need to make class attendance every day at universities. 我认为在大学里没必要每天点名。
  • optional [‘ɒpʃənl] adj. 可选择的,非强制的,随意的;选修的
    • 联想记忆:option (选择) + al → 可选择的
    • 例句:an optional course 一门选修课
    • 例句:Is geography an optional course, or does everyone have to learn it? 地理是选修课吗,还是每个人都必须学习它?
    • 拓展:option (n. 选择;选择权)
      heal [hiːl] v. 治愈,康复;调停
    • 例句:The wound took months to heal. 这个伤口花了几个月才愈合。
  • enable [ɪ’neɪbl] vt. 使能够,使成为可能
    • 词根记忆:en (使……) + able (能够的) → 使能够,使成为可能
    • 常见搭配:enable sb. to do sth. 使……能够做……
    • 例句:The bank service enables you to withdraw cash from your account at any time. 这种银行服务使你能随时从账户中取钱。
  • dismantle [dɪs’mæntl] vt. 拆除;废除,取消
    • 联想记忆:dis (去掉) + mantle (覆盖) → 拆除;废除
    • 例句:Most people have been forced to dismantle their individualistic homes and return to more conventional lifestyles. 大多数人被迫拆除了他们极具个性的房子,回归更加传统的生活方式。
  • wage [weɪdʒ] n. 工资;[常 pl.] 报酬
    • 例句:In this company, wages are paid at the end of every month. 这家公司每到月末发工资。
      landscape [‘lændskeɪp] n. 风景,景色 vt. 对……作景观美化,美化 (自然环境等)
    • 例句:The landscape on the altiplano is the most beautiful I’ve ever seen. 高原上的风景是我所见过的最美的景色。
  • emotion [ɪ’moʊʃn] n. 感情;情绪
    • 词根记忆:e (出) + mot (动) + ion (表状态) → 心里释放出的东西 → 感情;情绪
    • 例句:Doing sports can be a good way to release suppressed emotion. 做运动是一个释放压抑情绪的好方法。
      commonwealth [‘kɒmənwelθ] n. 联邦;联合体;(the Commonwealth) 英联邦
    • 组合词:common (共同的) + wealth (财富) → 共创财富 → 联合体
    • 例句:George was a scientist at the Commonwealth Scientific and Industrial Research Organisation at that time. 那时乔治是 (澳大利亚) 联邦科学与工业研究组织的一名科学家。
  • newsletter [‘nju:zletər] n. 时事通讯,业务通讯
    • 组合词:news (消息,新闻) + letter (文字) → 时事通讯
    • 例句:There’s David West who has volunteered to be the club secretary, and one of the many jobs he will have is to send out newsletters to you regularly. 那位就是戴维·韦斯特,他自愿做俱乐部秘书,他有许多工作,其中之一就是定期给你们分发时事通讯。
  • periodical [ˌpɪəri’ɒdɪkl] n. 期刊,杂志 adj. 周期的,定期的
    • 来自 period (n. 时期,周期)
    • 例句:The professor’s paper has been issued in the latest periodical. 教授的论文已经发表在最新的一期期刊上。
    • 拓展:periodically (adv. 周期地;定期地,按时地)
    • 拓展:journal (n. 定期刊物,杂志);magazine (n. 杂志,期刊)
  • receptionist [rɪ’sepʃənɪst] n. 接待员
    • 例句:The patient goes to a receptionist and ask her about his disease. 那个病人走向接待员,向她询问他的病情。
  • security [sɪ’kjʊərəti] n. 安全,保障;抵押品;[pl.] 证券
    • 来自 secure (v. 保护,使安全;获得)
    • 常见搭配:security check 安全检查;job security 工作保障
    • 例句:Such insurance plan can offer your families financial security in the event of the loss of properties. 这种保险计划可以在你失去财产的情况下向你的家人提供经济保障。
  • clip [klɪp] n. (弹簧) 夹子;回形针;别针;弹夹;修剪;剪报;电影 (或电视) 片段 v. (用夹子、回形针等) 夹住,扣住;剪,修剪
    • 常见搭配:clip on 用夹子夹住
    • 例句:It is said that the U.S. produces 300 million aluminium paper clips each day. 据说美国每天生产三亿个铝制回形针。
    • 拓展:clutch (v. 抓住)
  • apace [ə’peɪs] adv. 快速地,急速地
    • 例句:The research went on apace. 研究进展迅速。
  • yield [jiːld] n. 产量 v. 出产 (作物);产生 (收益、效益等);放弃,屈服
    • 常见搭配:yield up 放纵;yield to 向……屈服;boost crop yield 提高作物产量
    • 例句:Higher yields have been achieved by increased irrigation and better crop breeding. 已通过增加灌溉和提高育种质量实现了产量的增长。
  • fair [feə(r)] adj. 公平的;合理的 adv. 公正地;公平合理地 n. 商品交易会;展销会
    • 例句:This part of the island is warmer than the southern half, but it wouldn’t be fair to say that the southern half is cold. 小岛的这部分区域比它的南部区域暖和,但是因此说南部冷是不合理的。
    • 拓展:unfair (adj. 不公平的)

3. 无重复字符的最长子串

题目

3. 无重复字符的最长子串

给定一个字符串 s ,请你找出其中不含有重复字符的 最长 

子串

 的长度。

示例 1:

输入: s = "abcabcbb"
输出: 3 
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。

示例 2:

输入: s = "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。

示例 3:

输入: s = "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
     请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。

提示:

  • 0 <= s.length <= 5 * 104
  • s 由英文字母、数字、符号和空格组成

解答

滑动窗口的思路

class Solution {
    func lengthOfLongestSubstring(_ s: String) -> Int {
        var charMap: [Character: Int] = [:]
        var start = 0
        var maxLength = 0

        let count = s.count
        
        for i in 0..<count {
            // 1、取出当前字符
            let char = s[s.index(s.startIndex, offsetBy: i)]

            // 2、如果这个字符已经在字典里,取出他上次的位置,更新起点为上次出现的位置的后面
            if let lastIndex = charMap[char], start <= lastIndex {
                start = lastIndex + 1
            }

            // 3、更新到字典里
            charMap[char] = i

            // 4、计算新的长度为当前index-起点,并更新长度
            maxLength = max(maxLength, i - start + 1)

        }

        return maxLength
    }
}

2. 两数相加

题目

2. 两数相加

给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。

请你将两个数相加,并以相同形式返回一个表示和的链表。

你可以假设除了数字 0 之外,这两个数都不会以 0 开头。

示例 1:

输入:l1 = [2,4,3], l2 = [5,6,4]
输出:[7,0,8]
解释:342 + 465 = 807.

示例 2:

输入:l1 = [0], l2 = [0]
输出:[0]

示例 3:

输入:l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9]
输出:[8,9,9,9,0,0,0,1]

提示:

  • 每个链表中的节点数在范围 [1, 100] 内
  • 0 <= Node.val <= 9
  • 题目数据保证列表表示的数字不含前导零

解答

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     public var val: Int
 *     public var next: ListNode?
 *     public init() { self.val = 0; self.next = nil; }
 *     public init(_ val: Int) { self.val = val; self.next = nil; }
 *     public init(_ val: Int, _ next: ListNode?) { self.val = val; self.next = next; }
 * }
 */
class Solution {
    func addTwoNumbers(_ l1: ListNode?, _ l2: ListNode?) -> ListNode? {
        /*
        哑:哑节点开头,哑节点固定,结果返回哑节点的后继
        标:标识两个遍历的节点和一个生成的新节点
        移:while循环向前走
        进:无法移动后再处理进位
        */
        let dummyHead = ListNode()
        var currentNode = dummyHead
        var carry = 0

        var p = l1
        var q = l2

        while p != nil || q != nil {
            /*
            只要不是都走到尽头,都要进入这里
            */
            let pValue = p?.val ?? 0
            let qValue = q?.val ?? 0
            var sum = pValue + qValue + carry

            // 1、是否要进位
            carry = sum / 10
            // 2、新节点的后继(value为当前相加取余)
            currentNode.next = ListNode(sum % 10)

            // 3、往后移动
            currentNode = currentNode.next!
            p = p?.next
            q = q?.next
        }

        /*
        两个单链表都走到尽头了,如果存在进位,要追加一个后继
        这个节点的value只能是1,实际是最高位
        */
        if carry > 0 {
            currentNode.next = ListNode(carry)
        }

        return dummyHead.next
        
    }
}

1. 两数之和

题目

1. 两数之和

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target  的那 两个 整数,并返回它们的数组下标。

你可以假设每种输入只会对应一个答案,并且你不能使用两次相同的元素。

你可以按任意顺序返回答案。

示例 1:

输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。

示例 2:

输入:nums = [3,2,4], target = 6
输出:[1,2]

示例 3:

输入:nums = [3,3], target = 6
输出:[0,1]

提示:

  • 2 <= nums.length <= 104
  • -109 <= nums[i] <= 109
  • -109 <= target <= 109
  • 只会存在一个有效答案

题解

class Solution {
    func twoSum(_ nums: [Int], _ target: Int) -> [Int] {
        /*
        从头开始遍历,看剩下的数里是否有相加等于目标数
        时间复杂度: O(n2)
        优化:
            遍历一次数组,生成一个字典[int: int],
            valueForKey来找index
        */

        let count = nums.count
        if count == 0 {
            return []
        }
        for index in 0..<count {
            let currentValue = nums[index]
            for targetIndex in 0..<count {
                if index == targetIndex {
                    continue
                }
                let targetValue = nums[targetIndex]
                if currentValue + targetValue == target {
                    return [index, targetIndex]
                }
            }
        }
        return []
    }
}

iOS KeyboardObserving(beta)

// TODO: 开篇

  • 常见问题(本文要解决的)
  • 思路(用protocol个extension)

1、在Notification的extension中方便快捷地获取键盘的动画时长和尺寸

extension Notification {

    public var keyboardSize: CGSize? {
        return (userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue.size
    }

    public var keyboardAnimationDuration: TimeInterval? {
        return userInfo?[UIResponder.keyboardAnimationDurationUserInfoKey] as? TimeInterval
    }

}

2、定义协议,协议中需要暴露两方面的接口,一是开启和结束键盘状态的监听,二是监听到键盘升降之后的action

public protocol KeyboardObserving: AnyObject {
    func startObservingKeyboard()
    func stopObservingKeyboard()

    func keyboardWillShow(notification: Notification)
    func keyboardWillHide(notification: Notification)
}

UIViewController有生命周期,需要在特定的阶段开启或取消对通知的监听,在willAppearwillDisappear阶段调用func startObservingKeyboard()func stopObservingKeyboard()是比较方便的。尤其是present出另一个viewController的情况下,如果没有取消对键盘的监听,那么第二个ViewController触发键盘可能会影响第一个控制器执行升起键盘后的动画。

这个协议希望被需要监听键盘即将升降的对象来遵守,通常是UIViewController,所以我们在默认实现中也通过where Self: UIViewController限制为UIViewController

public extension KeyboardObserving where Self: UIViewController {

    func startObservingKeyboard() {
        NotificationCenter.default.addObserver(forName: UIResponder.keyboardWillShowNotification, object: nil, queue: nil) { [weak self] (notification) in
            self?.keyboardWillShow(notification: notification)
        }
        NotificationCenter.default.addObserver(forName: UIResponder.keyboardWillHideNotification, object: nil, queue: nil) { [weak self] (notification) in
            self?.keyboardWillHide(notification: notification)
        }
    }

    func stopObservingKeyboard() {
        NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillShowNotification, object: nil)
        NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillHideNotification, object: nil)
    }

}

3、用例

class MediaBrowseViewController: UIViewController, KeyboardObserving {
   override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        // 在生命周期的即将显示阶段 调用协议中的开启监听方法的默认实现
        self.startObservingKeyboard()
    }

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        // 在生命周期的即将消失阶段 调用协议中的结束监听方法的默认实现
        self.stopObservingKeyboard()
    }

    // MARK: - KeyboardObserving
    func keyboardWillShow(notification: Notification) {
        self.replyInputView.showMaskIfPossible()
        if let height = notification.keyboardSize?.height, let duration = notification.keyboardAnimationDuration {
            // 这里执行键盘即将升起时UI变化的任务
            UIView.animate(withDuration: duration) {
                self.replyInputView.willAscend()
                self.replyInputView.snp.updateConstraints { make in
                    make.bottom.equalToSuperview().offset(-height)
                }
                self.view.layoutSubviews()
            }
        }
    }

    func keyboardWillHide(notification: Notification) {
        if let duration = notification.keyboardAnimationDuration {
            // 这里执行键盘即将降下时UI变化的任务
            UIView.animate(withDuration: duration) {
                self.replyInputView.willDescend()
                self.replyInputView.snp.updateConstraints { make in
                    make.bottom.equalToSuperview().offset(-tabbarHeight)
                }
                self.view.layoutIfNeeded()
            }
        }
    }
}

4、关键词:

  • UIViewController的生命周期
  • protocol
  • extension

iOS 一个易用的MaskableProtocol(beta)

// TODO: -开篇

  • 什么场景会遇到什么问题(这篇文章需要解决的)
  • 设计的原则
  • 解释过程
  • 总结

协议部分

public protocol MaskableProtocol: AnyObject {
    var maskableHelper: MaskableHelper { get set }
    func showMaskIfPossible()
    func hideMaskIfPossible()
}

协议的默认实现

private var gestureMaskViewKey: UInt8 = 0
private var maskableHelperKey: UInt8 = 0
public extension MaskableProtocol where Self: UIView {
    private var gestureMaskView: UIView? {
        get {
            return objc_getAssociatedObject(self, &gestureMaskViewKey) as? UIView
        }
        set {
            objc_setAssociatedObject(self, &gestureMaskViewKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }

    var maskableHelper: MaskableHelper {
        get {
            return objc_getAssociatedObject(self, &maskableHelperKey) as? MaskableHelper ?? MaskableHelper()
        }
        set {
            objc_setAssociatedObject(self, &maskableHelperKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }

    func showMaskIfPossible() {
        guard gestureMaskView == nil, let superview = self.superview else { return }
        UIView.performWithoutAnimation {
            gestureMaskView = UIView()
            gestureMaskView?.backgroundColor = UIColor(white: 0, alpha: 0.5)
            let tap = UITapGestureRecognizer(target: maskableHelper, action: #selector(maskableHelper.executeMaskAction))
            gestureMaskView?.addGestureRecognizer(tap)
            superview.insertSubview(gestureMaskView!, belowSubview: self)

            guard let maskView = gestureMaskView else { return }
            maskView.frame = superview.bounds
        }
    }

    func hideMaskIfPossible() {
        self.gestureMaskView?.removeFromSuperview()
        self.gestureMaskView = nil
    }
}

这里在extension中给UIView设置了两个关联对象,分别是:

  • gestureMaskView: UIView
    • 作用:添加到目标view的superview上,用于响应手势事件
  • maskableHelper: MaskableHelper
    • 作用:由于swift的extension中不支持运行时,无法直接使用Selector,需要借助一个类来中转Action

借助一个辅助类

public class MaskableHelper: NSObject {
    var maskAction: (() -> Void)?

    init(action: (() -> Void)? = nil) {
        self.maskAction = action
        super.init()
    }

    @objc func executeMaskAction() {
        maskAction?()
    }
}

应用

让需要作用的UIView遵守MaskableProtocol,并初始化一个MaskableHelper

class ContentInputView, MaskableProtocol {

    // MARK: - Lazy Loading
    internal lazy var maskableHelper: MaskableHelper = {
        let helper = MaskableHelper()
        helper.maskAction = { [weak self] in
            guard let `self` = self else { return }
            self.hideMaskIfPossible()
            self.endEditing(true)
        }
        return helper
    }()
} 

下需要显示Mask的时候调用协议中的func showMaskIfPossible( )即可

// MARK: - KeyboardObserving
func keyboardWillShow(notification: Notification) {
    self.replyInputView.showMaskIfPossible()
    if let height = notification.keyboardSize?.height, let duration = notification.keyboardAnimationDuration {
        UIView.animate(withDuration: duration) {
            self.replyInputView.willAscend()
            self.replyInputView.snp.updateConstraints { make in
                make.bottom.equalToSuperview().offset(-height)
            }
            self.view.layoutSubviews()
        }
    }
}

关键词

  • 关联对象
  • 协议
  • 协议的默认实现

iOS证券交易App组件化方案

一、前言

1.1 什么是组件化

组件:强调物理拆分,以便复用。例如:图片库网络库等。

模块:强调逻辑拆分,以便解耦。例如:订单模块账户模块等。

介于业界习惯称之为组件化,所以我们继续使用这个术语。【组件化 = 功能组件 + 业务模块

1.2 为什么要组件化

  • 解决代码(工程)臃肿问题,提高编译速度。
  • 核心业务模块化,职责分离,提高代码安全性。
  • 通用功能组件化,提高复用率及完整性。
  • 协议编程具体化,形成独立子系统,可灵活配置。
  • 提高模块自治力,独立升级部署,相互间不形成绝对依赖。
  • 支持异构,提升系统技术多元化能力。

二、业界方案

2.1 组件化演进之路

// TODO

2.2 微服务概念

2.2.1 三个⻆色

服务中介:联系服务提供者服务消费者的桥梁。

服务提供者:将自己提供的服务地址注册到服务中介。

服务消费者:从服务中介那里查找自己想要的服务的地址,然后享受这个服务。

2.2.2 三个⻆色在iOS组件化中的体现

iOS客户端是一个单工程设计,简单说就是APP作为一个独立个体,所有的业务生命周期与APP是一致的。并不能真正实现微服务中的“每个服务完全独立生存、管理、销毁”。为此,组件化更多是解决职责分离高复用独立发布 (非独立运行)问题。

iOS中服务提供者通常指的是业务提供方,比如:行情模块需要调用交易模块交易记录接口,此时交易模块即作为服务提供者。而行情模块作为服务需求方,即为服务消费者。由于模块与模块之间可能处于同一级,也可以不同 级。按照《软件工程设计:分层概述》原则,同一级模块间不能相互依赖,也就是不能相互直接调用。此时就需要 一个服务中介来解决模块间通信问题

2.3 组件间通信常⻅方案

2.3.1 基于路由 URL UI ⻚面统跳管理

概念

统跳路由是⻚面解耦的最常⻅方式,大量应用于前端⻚面
通过把一个 URL 与一个⻚面绑定,需要时通过 URL 可以方便的打开相应⻚面。 比如

bebull://quote/stockDetail?stock_id=00700 /**个股报价⻚**/ 

优点

  • 多端一致,H5、iOS、Android、Weex/RN/Cameron 、PC、Mac等。
  • 浏览器、其他APP可以通过openURL直接唤起APP指定⻚面。
  • 可结合服务端下发配置表,动态绑定/解绑指定URL实现⻚面灰度。

缺点

  • 无法支撑较为复杂操作及数据传输模型,比如跨模块⻓调用链场景。
2.3.2 基于反射的远程接口调用封装

概念

此类型适合动态语言,借助反射技术进行动态化调用,比如OCRuntime,可以采用以下方式调用:

Class quoteManager = NSClassFromString(@"QuoteManager"); 
NSArray *stockList = [quoteManager performSelector:@selector(getStockList)];

优点

  • 调用较为方便
  • 代码自动补全
  • 编译检查有效

缺点

  • 存在hardcode问题
  • Swift静态语言不支持Runtime
2.3.3 基于面向协议思想的服务注册方案

概念

参考后端Dubbo服务框架,通过服务注册的方式来实现远程接口调用的。 即每个模块提供自己对外服务的协议声明(Protocol),然后将此声明注册到服务中介。调用方能从服务中介看到 存在哪些服务接口,然后直接调用即可。

@protocol QuoteModuleService
- (NSArray * _Nullable)getStockList;
@end
@interface QuoteModule : NSObject<QuoteModuleService>
@end
@implementation QuoteModule
+ (void)load {
  [ServiceManager registerService:@protocol(QuoteModuleService)
                  withModule:self.class];
}
- (NSArray * _Nullable)getStockList {
  return nil;
}
@end

id<QuoteModuleService> module = [ServiceManager
objByService:@protocol(QuoteModuleService)];
NSArray *stockList = [module getStockList];

优点

  • 调用方便
  • 代码自动补全
  • 无需hardcode,面向协议,减少对接错误⻛险

缺点

  • 高度依赖协议,协议变更时容易导致所有依赖方编译失败。
  • 存在服务注册过程,有一定性能开销。
2.3.4 基于通知的广播方案

概念

直接基于系统的 NSNotificationCenter

优点

  • 实现简单。
  • 适合一对多场景。

缺点

  • 不适合复杂数据传输场景。
  • 同步调用不方便。

三、架构设计思路

3.1 目标

  • 业务模块分离,业务职责单一,划清边界。
  • 业务模块间通信灵活且统一化。
  • 业务模块间通信协议严格标准化,具备准入原则。
  • 通用逻辑独立化,构建稳定后采用二进制形式链接。
  • ⻚面多端统一性,方便后续PAAS化(可由服务端自主下发配置,灵活管理⻚面调用及组合)。
  • 代码安全,只开放必要的模块代码权限。
  • 服务异构化,后续部分模块可以采用更多语言如c++python等开发后引入。
  • 设计模式规范化,明确各场景采用MVCMVVM等,如何组织类关系等。

3.2 组件间通信场景

3.2.1 场景一:UI独立⻚面

采用 路由 URL UI ⻚面统跳管理方案 ,实现跨端 + 端内任何场景可直接唤起指定⻚面能力。

3.2.2 场景二:跨模块UI嵌套

采用 基于面向协议思想的服务注册方案 ,通过 BNBee组件中心UIService 进行服务调用,获得指定的 View、VC。

3.2.3 场景三:跨模块数据传输

采用 基于面向协议思想的服务注册方案 ,通过 BNBee组件中心OpenService 进行服务调用,提供同步返回

(sync)和 异步返回(async)能力。

四、架构分层

4.1 图示

4.2 各层职责

总体分为 业务层公共层基础框架层 三层。

业务层

  • 承担业务层面相关工作
  • 主要包括VCViewModelViewModelDCManagerAPIClient
  • 目前阶段分为行情交易资讯账户公共主体五类

公共层职责

  • 承担整体性非业务相关的相关工作。
  • 主要包括公共相关事务(如BNURLHelper),组件间通信API、Model,以及皮肤资源整合。
  • 目前阶段分为公共基础平台、业务间通信API、皮肤资源中心。

基础框架层职责

  • 包含一些日常使用,趋于稳定的库。
  • 主要分为自研和第三方依赖两大类。
  • 自研部分采用framework静态库方式,基于pod引入。

4.3 各层间依赖关系

  • 同层之间禁止直接依赖,通信方式通过BNBee组件服务中心。提供方提供具体实现,将协议定义于BNUAPI工程中;消费方于BNUAPI中获得对应API及model。
  • 上层可以直接引用下层,也可以跨层下级引用
  • 下层禁止引用上层。

4.4 模块说明

  • 行情模块:包括行情一级tab下的自选列表、市场列表、个股报价⻚等。
  • 交易模块:包括交易一级tab下的开户、资金账户、持仓、买入卖出、交易记录、入金出金等。
  • 资讯模块:包括资讯一级tab下的资讯列表、资讯详情⻚等。
  • 账户模块:包括我的一级tab下的用户登录、注册、个人资料等。
  • 公共基础平台:主要涵盖与业务无关的部分,包括暂时找不到基础框架层可以下沉的暂留组件,比如:WebView、 tabbar等。
  • 业务间通信API:主要负责上层业务模块的组件间通信API协议定义、传输model定义、业务通知key等。 皮肤资源中心:存放所有必牛项目的图片、lottie动画等资源。

4.5 模块内结构

五、BNBee(待补充)

5.1 基本能力

5.2 URL注册绑定

5.3 面向协议服务注册

六、自研框架库

6.1 目标

  • 将重要且需要稳定的模块独立出来,抽离成framework,实现复用性稳定性安全性目标。
  • 标准化一些常用逻辑,做到多业务一致。
  • 代码安全,只开放必要的代码权限。
  • 服务异构化,后续可以采用更多语言如c++python等开发更多底层框架。

6.2 组件库

  • 网络组件库:负责socket⻓连接管理、HTTPS短链接生命周期、连接、安全、可靠性管理。
  • 组件服务中心:负责管理组件间通信,提供基于URL注册、协议绑定等方案管理。
  • 日志组件库:分级日志系统,对infowarningerrorfile及日志收集存取上报管理。
  • 开发组件库:日常开发常用的工具类系统类分类等。
  • 数据上报组件库:直接接驳三方数据上报平台,提供与上报平台无关的通用接口,包括曝光时⻓曝光量统计接口
  • 分享组件库:主要提供通用分享组件,包括分享到QQ微信Twitter等。
  • UI组件库:主要沉淀通用UI组件,如嵌套Scrollviewtabbar等。
  • 数据管理组件库:主要包装内存级缓存磁盘级缓存的接口,后端对接沙盒、SQLite数据库等。
  • 皮肤组件库:主要提供style定义系统,用于约定常用UI组件如UIButtonUIView的多肤管理。
  • 健康防护系统:防范常⻅类型crash兜底,启动连续crash绕行等方案。
  • k线组件库:k线组件作为核心性能指标,沉淀出来方便后续各业务使用。

七、第三方依赖库

7.1 设定准入标准

券商APP的安全性不容小觑,对于第三方依赖库的引入需持有谨慎的态度;因此后期需要增加第三方依赖库的准入 机制,形成选型评审安全鉴定引入的原则。同时,尽量剔除一些功能重复、失去维护、功能滞后的三方库, 保证APP包大小启动性能等各项指标。

7.2 选型需明确

如:选新不选旧 or 稳定大于能力?Swift实现的优先?轻量化还是重量级?是否跨端配套⻬全?等等问题,需要有 明确的标准,组件化工作落地后,需要再明确这块,保证快捷接入的同时,可以更稳定、更一致。


腾讯云搭建网站

刚刚完成一半,简单记录目前的流程,等后续备案完成后再梳理一遍

一、本地开发静态站点

  • VS Code
  • 创建站点
  • 编辑以下:
    • html
    • css
    • js

二、购买腾讯云轻量应用服务器(Lighthouse)

  • 四百多一年即可

三、使用FTP客户端连接到云服务器

  • 公有IP
  • 端口号 21
  • user name
  • password
  • 很重要的是在连接过程中会使用到3000-4000这个范围内的端口,需要在云服务器的防火墙开启这些端口,不然本地电脑会连不上云服务器的FTP

四、备案

  • 明天继续写