-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathatom.xml
536 lines (251 loc) · 359 KB
/
atom.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>Siz Long</title>
<link href="https://longsizhuo.github.io/atom.xml" rel="self"/>
<link href="https://longsizhuo.github.io/"/>
<updated>2025-03-31T03:42:04.907Z</updated>
<id>https://longsizhuo.github.io/</id>
<author>
<name>loong loong</name>
</author>
<generator uri="https://hexo.io/">Hexo</generator>
<entry>
<title>基础前端</title>
<link href="https://longsizhuo.github.io/post/8a05667d.html"/>
<id>https://longsizhuo.github.io/post/8a05667d.html</id>
<published>2025-03-31T03:42:04.907Z</published>
<updated>2025-03-31T03:42:04.907Z</updated>
<content type="html"><![CDATA[<h1 id="Javascript-全局作用域"><a href="#Javascript-全局作用域" class="headerlink" title="Javascript 全局作用域"></a>Javascript 全局作用域</h1><h2 id="作用域"><a href="#作用域" class="headerlink" title="作用域"></a>作用域</h2><ol><li>Javascript 作用域为嵌套结构。</li><li>最外层作用域为全局</li></ol><h2 id="全局变量种类"><a href="#全局变量种类" class="headerlink" title="全局变量种类"></a>全局变量种类</h2><table><thead><tr><th>全局声明变量(普通变量)</th><th>const、let、class</th><th>❌ 不可以 (undefined)</th></tr></thead><tbody><tr><td>全局对象变量</td><td>var、function</td><td>✅ 可以访问</td></tr></tbody></table><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> a = <span class="number">1</span>; <span class="comment">// 全局声明变量 (window.a 为 undefined)</span></span><br><span class="line"><span class="keyword">var</span> b = <span class="number">2</span>; <span class="comment">// 全局对象变量 (window.b 为 2)</span></span><br></pre></td></tr></table></figure><h2 id="全局对象"><a href="#全局对象" class="headerlink" title="全局对象"></a>全局对象</h2><ol><li>浏览器环境下,全局对象为 window</li><li>Node.js 环境下,全局对象为 global</li><li>所有环境下,全局对象为 globalThis</li></ol><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> x = <span class="number">10</span>;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">window</span>.<span class="property">x</span>); <span class="comment">// 10</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(globalThis.<span class="property">x</span>); <span class="comment">// 10</span></span><br></pre></td></tr></table></figure><h2 id="最佳实践"><a href="#最佳实践" class="headerlink" title="最佳实践"></a>最佳实践</h2><ol><li>不推荐使用 var 声明全局变量。</li><li>荐使用 const 和 let 减少全局污染。</li></ol>]]></content>
<summary type="html"><h1 id="Javascript-全局作用域"><a href="#Javascript-全局作用域" class="headerlink" title="Javascript 全局作用域"></a>Javascript 全局作用域</h1><h2 id="作用域"><a h</summary>
<category term="frontend" scheme="https://longsizhuo.github.io/tags/frontend/"/>
<category term="javascript" scheme="https://longsizhuo.github.io/tags/javascript/"/>
</entry>
<entry>
<title>Next.js Fundamentals</title>
<link href="https://longsizhuo.github.io/post/33379c34.html"/>
<id>https://longsizhuo.github.io/post/33379c34.html</id>
<published>2025-03-30T13:00:00.000Z</published>
<updated>2025-03-31T03:47:22.248Z</updated>
<content type="html"><![CDATA[<h2 id="1-Classification-of-important-knowledge-points-and-key-points-list"><a href="#1-Classification-of-important-knowledge-points-and-key-points-list" class="headerlink" title="1. Classification of important knowledge points and key points list"></a>1. Classification of important knowledge points and key points list</h2><p><strong>It is recommended to organize the knowledge into the following modules</strong>, and each module lists common “eight-part essay” test points for quick review:</p><h3 id="1-HTML-and-CSS-Basics"><a href="#1-HTML-and-CSS-Basics" class="headerlink" title="1. HTML and CSS Basics"></a>1. HTML and CSS Basics</h3><ul><li><strong>CSS box model</strong>: Understand the composition of the box (content, padding, border, margin) and its impact on element size.</li><li><strong>CSS selector priority</strong>: Master the priority calculation rules when styles conflict (inheritance < element inline style < <code>!important</code>, etc.).</li><li><strong>Element horizontal and vertical centering</strong>: Familiar with a variety of centering layout methods, such as using positioning + <code>margin</code>, positioning + <code>transform</code>, or using Flexbox to achieve centering.</li><li><strong>Rearrangement and redrawing</strong>: Understand the difference and triggering conditions between rearrangement (reflow) and redrawing. Rearrangement is caused by layout changes (such as size and position changes), and the layout needs to be recalculated; redrawing is when the appearance style changes but the layout remains unchanged, and only the pixels are redrawn.</li></ul><h3 id="2-JavaScript-and-ES6"><a href="#2-JavaScript-and-ES6" class="headerlink" title="2. JavaScript and ES6"></a>2. JavaScript and ES6</h3><ul><li><strong>Prototype and prototype chain</strong>: Understand the mechanism of JavaScript prototype chain to implement inheritance. The prototype is essentially an object used to share properties and methods; the instance is linked to the constructor’s <code>prototype</code> through <code>__proto__</code> to implement property lookup.</li><li><strong>Closure</strong>: Master the concept and function of closure. A closure is a function that can access variables in the scope of another function, often created by creating another function inside a function. Closures can be used to encapsulate private variables and avoid global variable pollution.</li><li><strong><code>this</code> binding</strong>: Understand the pointing rules of <code>this</code> in different scenarios (functions point to the global object when called directly; method calls point to the object that calls it; constructor calls point to new instances; <code>call/apply</code> can explicitly change <code>this</code>). Note that arrow functions do not have their own <code>this</code> and will capture the outer <code>this</code>.</li><li><strong>Event loop and asynchrony</strong>: Understand the browser’s JavaScript <strong>Event Loop (Event Loop)</strong> mechanism and distinguish between macrotasks and microtasks. JavaScript uses a single thread to run, and through the event loop, it continuously checks and executes tasks in the task queue. Master the execution order of asynchronous mechanisms such as <code>setTimeout</code>, <code>Promise</code>, and <code>async/await</code>.</li><li><strong>ES6+ New Features</strong>: Familiar with common ES6/ES7 features and usage, such as the scope difference between <code>let</code>/<code>const</code>, arrow function binding lexical <code>this</code>, <code>Set/Map</code> container types, <code>Promise</code> and <code>async/await</code> to achieve asynchrony, class (Class) syntax sugar and inheritance, etc. These features are often high-frequency topics in interviews, and their uses and advantages and disadvantages should be explained.</li></ul><h3 id="3-Browser-Principles"><a href="#3-Browser-Principles" class="headerlink" title="3. Browser Principles"></a>3. Browser Principles</h3><ul><li><strong>Browser Rendering Process</strong>: Understand the basic process from input HTML to page rendering: build DOM tree -> build CSSOM tree -> merge to generate rendering tree -> layout (Reflow) -> drawing (Paint). Know how CSS affects rendering (such as external CSS loading will block rendering tree construction), etc.</li><li><strong>Browser multi-process architecture</strong>: Understand the process division of modern browsers (such as browser main process, rendering process, network process, etc.) and the difference between <strong>process</strong> and <strong>thread</strong>. Processes have independent memory space and crashes do not affect each other; threads are execution units within processes and share memory. Understand that the rendering process in Chrome browser is multi-threaded (including GUI rendering thread, JS engine thread, etc.).</li><li><strong>DOM event mechanism</strong>: Master the three stages of browser event flow: capture → target → bubbling. Event capture propagates downward from ancestor nodes, while event bubbling propagates upward from targets. Understand how to use the third parameter of <code>addEventListener</code> to control the binding phase, and use <code>stopPropagation()</code> to stop bubbling.</li><li><strong>Script loading strategy</strong>: Understand the difference between the <code>async</code> and <code>defer</code> attributes in the <code><script></code> tag: when there is no attribute, the browser parses and executes the script synchronously; <code>async</code> means that the script is downloaded asynchronously and executed immediately after downloading (not guaranteed in order); <code>defer</code> means that the script is downloaded asynchronously but delayed until HTML parsing is completed and then executed in order.</li><li><strong>Browser storage</strong>: Understand the differences between several <strong>front-end storage</strong> methods: Cookies, <code>localStorage</code>, <code>sessionStorage</code>, <code>IndexedDB</code>, etc. For example, Cookies will be automatically attached to the request, with a small capacity and mostly used to save session identifiers, <code>localStorage</code> has a large capacity and persists, and <code>sessionStorage</code> is cleared after the session ends.</li><li><strong>Browser cache mechanism</strong>: Master HTTP cache strategies, such as the principles of <strong>strong cache</strong> (Expires/Cache-Control) and <strong>negotiated cache</strong> (Last-Modified/Etag). Be able to explain how the browser determines that the cache is valid and returns 304.</li></ul><h3 id="4-Network-and-protocol"><a href="#4-Network-and-protocol" class="headerlink" title="4. Network and protocol"></a>4. Network and protocol</h3><ul><li><strong>Differences between GET and POST</strong>: Clarify the differences in semantics and implementation between HTTP GET and POST. For example: GET is generally used to obtain resources, and the parameters are attached to the URL and have a length limit; POST is used to submit data, placed in the request body, and has no length limit; GET requests can be cached by the browser while POST will not be automatically cached; POST is relatively safer in terms of security, etc.</li><li><strong>HTTP1.1 and HTTP2</strong>: Understand the main improvements of HTTP/1.1 over HTTP/2. For example, HTTP/2 uses binary framing transmission, supports <strong>multiplexing</strong> (one connection with multiple requests concurrently, no head-of-line blocking of the HTTP layer, but the head-of-line blocking of the TCP layer still exists), header compression, etc. Know the further optimization of HTTP/3 based on QUIC (can be briefly mentioned).</li><li><strong>Network Communication Basics</strong>: Master the basic process of TCP three-way handshake and four-way handshake, and understand the role of TLS/SSL handshake in HTTPS. Although it is not a pure front-end scope, the interview may involve simple questions and answers.</li><li><strong>Other protocols/mechanisms</strong>: Understand the difference between <strong>WebSocket</strong> and HTTP (full-duplex communication, handshake upgrade protocol, etc.) and common application scenarios. Familiar with the meaning of <strong>HTTP status codes</strong> (especially 2xx, 3xx redirection, 4xx client errors such as 401/403/404, 5xx server errors). These are prepared and can be mentioned when answering HTTP-related questions.</li><li><strong>Request process and optimization</strong>: Be familiar with the whole process from entering the URL in the browser address bar to loading the page, including DNS resolution, TCP connection, sending requests, receiving responses, and browser rendering. Be able to explain methods to improve network loading performance in combination with cache, CDN, etc. (such as enabling CDN nearby access, reducing request size, etc.).</li></ul><h3 id="5-Security"><a href="#5-Security" class="headerlink" title="5. Security"></a>5. Security</h3><ul><li><strong>XSS Cross-site Scripting Attack</strong>: Understand the principle of XSS - attackers inject malicious script code into the target website and execute it on other users’ browsers to steal user data (such as cookies), etc. Master common preventive measures: <strong>Input filtering and escaping</strong> (HTML escape filtering of special characters for user input), <strong>Content Security Policy (CSP)</strong>, sensitive cookie settings <code>HttpOnly</code> to prevent script reading, etc.</li><li><strong>CSRF Cross-site Request Forgery</strong>: Understand the attack mechanism of CSRF - using the user’s logged-in status to send malicious requests in the user’s name without the user’s knowledge. Defense methods include: requesting to attach an anti-counterfeiting random token and verifying it, using <code>SameSite</code> strict cookies, adding verification code confirmation to key operations, etc.</li><li><strong>Same-origin policy and cross-domain</strong>: Understand the browser <strong>Same-Origin Policy</strong> restrictions on JavaScript, and know that the same origin means the same protocol, domain name, and port. Master several <strong>cross-domain solutions</strong>: such as setting <strong>CORS</strong> response headers on the server to allow cross-domain resource sharing, JSONP using <code><script></code> without same-origin restrictions (only supports GET), and reverse proxy forwarding mechanisms.</li><li><strong>Other security</strong>: Understand <strong>ClickJacking</strong> protection (disabling iframe nesting through <code>X-Frame-Options</code>), and how the front end can prevent crashes caused by <strong>malicious input</strong> (such as regular denial of service ReDoS), etc. When answering security questions, you can combine the security reinforcement measures encountered in actual projects to reflect your experience.</li></ul><h3 id="6-Front-end-framework-principles-mainly-React"><a href="#6-Front-end-framework-principles-mainly-React" class="headerlink" title="6. Front-end framework principles (mainly React)"></a>6. Front-end framework principles (mainly React)</h3><ul><li><p><strong>Virtual DOM and Diff</strong>: Understand the role of virtual DOM: add an abstract DOM tree cache between JS and real DOM, compare the new and old virtual DOMs through the Diff algorithm to efficiently update the real DOM, and avoid unnecessary DOM operations. Know React’s Diff strategy (same-layer comparison, list nodes require unique <code>key</code>, etc.) and the performance improvement it brings.</p></li><li><p><strong>React Fiber Architecture</strong>: Understand the reasons and principles for the introduction of Fiber in React16. React15’s coordinator uses recursive processing of component trees, and updates cannot be interrupted. Long-term updates will block the UI. Fiber splits update tasks into small, interruptible units (linked list form), uses browser idle time to execute, avoids long tasks blocking rendering, and realizes <strong>interruptible scheduling and rendering</strong>.</p></li><li><p><strong>React Lifecycle</strong>: Familiar with each stage of the React component lifecycle (Mounting -> Updating -> Unmounting) and the main lifecycle methods. For example, <code>componentDidMount/Update/WillUnmount</code>, etc., understand their calling order and typical uses. At the same time, understand the equivalent writing of Hooks for function components (such as the corresponding part of the life cycle of <code>useEffect</code>).</p></li><li><p><strong>Synthetic event mechanism</strong>: Understand how the React synthetic event model works. React does not bind event handlers directly to DOM nodes, but uses an event delegation mechanism <strong>to bind them uniformly to the root node (document)</strong>, which can improve performance and achieve consistent event behavior across browsers. Clarify the difference between this mechanism and native DOM events, such as event pools, syntheticEvent objects, etc.</p></li><li><p><strong>Error Boundary</strong>: Know how to capture errors in React, such as using <code>componentDidCatch</code> or <code>getDerivedStateFromError</code> to define an <strong>Error Boundary</strong> component to uniformly handle runtime errors of subcomponents to prevent errors from causing the entire application to crash (this can be mentioned briefly).</p></li><li><p><strong>Basic understanding of Vue</strong>: Although Vue is not actually used, you should have a <strong>rough understanding of the core principles of Vue</strong> to deal with comparison problems. For example: Vue achieves responsiveness through data hijacking (Vue2 uses <code>Object.defineProperty</code>, Vue3 uses <code>Proxy</code>); Vue templates will parse instructions and interpolation during the compilation phase, generate virtual DOM and update; the difference between Vue’s two-way data binding (v-model) and React’s one-way data flow, etc.</p></li><li><p><strong>React vs Vue</strong>: can compare the <strong>similarities</strong> and <strong>differences</strong> of the two frameworks. Similarities: Both use componentization and data-driven views, both use virtual DOM+Diff algorithm to optimize updates, and both have supporting routing and state management solutions. Differences:</p></li><li><p><strong>Core concept</strong>: Vue is a progressive framework, the core is responsive MVVM data binding; React is a library for building UI, emphasizing one-way data flow and functional UI.</p></li><li><p><strong>Syntax style</strong>: Vue recommends SFC single-file components (<code>template</code>+script+style, intuitive and easy to use), and also supports directive syntax and JSX; React forces the use of JSX, writing HTML and CSS in JavaScript with JSX/Inline Style (“All in JS”).</p></li><li><p><strong>Data update mechanism</strong>: Vue automatically tracks dependencies and efficiently updates DOM when data changes (a lot of built-in optimizations and syntax sugar), and developers do not need to handle it manually; React needs to trigger updates through <code>setState</code>, and may need to deal with performance issues (such as manually using <code>shouldComponentUpdate</code> or Memo to optimize), and many functions (such as global state management) rely on community libraries.</p></li><li><p><strong>Others</strong>: Vue2 is more declarative programming, and Vue3 begins to introduce a combination API close to React’s Hooks idea; Vue has built-in two-way binding to facilitate form processing, while React defaults to one-way data flow, and needs to write event processing to update the state. In general, both have their own advantages and disadvantages, and need to be selected according to the scenario. If you talk about it in the interview, you can first point out their common ideas and then explain the above differences.</p></li></ul><h3 id="7-Performance-optimization"><a href="#7-Performance-optimization" class="headerlink" title="7. Performance optimization"></a>7. Performance optimization</h3><ul><li><strong>Web page performance indicators</strong>: Understand the concepts of common page performance indicators such as first screen rendering time, white screen time, TTFB, FPS, etc., so as to facilitate discussion of performance experience with the interviewer. But more importantly, master the optimization methods.</li><li><strong>Resource loading optimization</strong>: Master the <strong>image lazy loading</strong> principle (delayed loading of off-screen images, users scroll to the visible area and then set the real <code>src</code> to trigger loading) and implementation methods (such as `<i- <strong>Others</strong>: Vue2 is more declarative programming, while Vue3 begins to introduce a combinational API close to React’s Hooks idea; Vue has built-in two-way binding to facilitate form processing, while React defaults to a one-way data flow, and you need to write your own event processing to update the state. In general, both have their advantages and disadvantages, and you need to choose according to the scenario. When talking about it during the interview, you can first point out their common ideas, and then use the above differences to explain.</li></ul><h3 id="7-Performance-optimization-1"><a href="#7-Performance-optimization-1" class="headerlink" title="7. Performance optimization"></a>7. Performance optimization</h3><ul><li><strong>Web page performance indicators</strong>: Understand the concepts of common page performance indicators such as first screen rendering time, white screen time, TTFB, FPS, etc., so that you can discuss performance experience with the interviewer. But more importantly, master the optimization method.</li><li><strong>Resource loading optimization</strong>: Master the <strong>image lazy loading</strong> principle (delayed loading of off-screen images, users scroll to the visible area and then set the real <code>src</code> to trigger loading) and implementation methods (such as <code><img></code> using <code>data-src</code> + listening to <code>scroll</code> events or IntersectionObserver). Understand <strong>code splitting</strong> and on-demand loading, and use Webpack and other methods to split bundles by route or component to reduce the size of first-screen resources.</li><li><strong>Function throttling and debounce</strong>: Understand the application of <strong>throttling</strong> and <strong>debounce</strong> technologies in the optimization of high-frequency events such as scrolling and input. Throttling allows a function to execute at a fixed frequency under continuous triggering (at most once in n seconds); debounce combines multiple triggers into the last execution (wait for n seconds after the trigger is completed). Be able to give examples of usage scenarios, such as throttling for scrolling event processing, debounce for input box search to prevent continuous requests, etc.</li><li><strong>Reduce reflow and redrawing</strong>: Optimize DOM operations to minimize the number and scope of Layout/Reflow. Specific measures include: avoid frequent direct style changes, prioritize batch changes or use <code>class</code> switching; avoid frequent insertion and deletion of nodes in the DOM tree. If necessary, you can first <code>display:none</code> the element (trigger a reflow first), and then display it after the operation is completed; use <code>transform</code> or <code>opacity</code> to trigger the synthesis layer for large animations to avoid repeated reflow; avoid using <code>table</code> layout, etc.</li><li><strong>Cache and resource optimization</strong>: use browser cache (strong cache/negotiation cache) to reduce requests; enable Gzip/Brotli compression to transmit resources; place commonly used static resources on CDN to increase access speed; use browser offline storage (such as Service Worker cache) to improve revisit performance, etc.</li><li><strong>Build package optimization</strong>: optimize front-end code performance through build tools. Typical methods include: <strong>Code compression obfuscation</strong> (reduce file size), <strong>Tree-Shaking</strong> (tree-shaking optimization deletes unreferenced code), <strong>SplitChunks</strong> split code, lazy loading by route, extracting public libraries, enabling package cache, etc. In addition, using production mode to build and remove development and debugging code, and properly configuring the optimization option of webpack are also common interview points.</li><li><strong>Performance monitoring</strong>: Familiar with basic performance monitoring methods, such as using Chrome DevTools Performance to record and analyze frame rate and call stack, and using Lighthouse for performance scoring. Although the interview may not ask about the use of tools in detail, it will be a plus if you can show your ability to monitor and locate performance problems.</li></ul><h3 id="8-Front-end-engineering-and-modularization"><a href="#8-Front-end-engineering-and-modularization" class="headerlink" title="8. Front-end engineering and modularization"></a>8. Front-end engineering and modularization</h3><ul><li><strong>Version control (Git)</strong>: Understand common Git commands (such as clone, branch, add, commit, push, etc.) and team collaboration processes. In particular, you need to master the difference between merge and rebase in the branch merge strategy: merge will generate a new merge commit and retain the historical fork of the branch; rebase will replay the branch commits sequentially at the top of the target branch without generating additional fork points. Large companies may pay attention to your understanding of team collaboration and code management.</li><li><strong>Building tools (Webpack)</strong>: Frequently tested Webpack principles and configurations. Need to know the difference between <strong>Loader</strong> and <strong>Plugin</strong>: Loader is essentially a file converter, used to process non-JS resources and convert them into modular JS; Plugin is hooked into the Webpack life cycle to extend Webpack functions, such as packaging optimization. Be familiar with several typical Loaders/Plugins (such as <code>babel-loader</code> converting ES6 to ES5, <code>file-loader</code> processing images, <code>HtmlWebpackPlugin</code> automatically generating HTML, etc.).</li><li><strong>Webpack hot update HMR</strong>: Understand the principle of Webpack hot module replacement (Hot Module Replacement). That is, in development mode, Webpack-dev-server establishes a WebSocket connection, and when it detects changes in the source code, it pushes the new module code to the browser through WebSocket and replaces the old module without refreshing the entire page. Can briefly describe the process and benefits of HMR (preserving application status and improving development efficiency).</li><li><strong>Babel Transpilation</strong>: Master the process of Babel converting ES6+ code to backward compatible JS. Including: Parsing – Parsing the source code into an abstract syntax tree (AST); Transforming – Transforming AST nodes according to the configured plugin presets (such as arrow functions to ordinary functions, etc.); Generating – Regenerate JS code based on the converted AST. This process reflects the compilation mechanism of front-end engineering, and senior interviews may ask in depth.</li><li><strong>Lint and Unit Testing</strong>: Understand code quality tools such as ESLint rule customization, and understand how to encapsulate custom ESLint plug-ins (know its basic mechanism of traversing AST, which can be briefly mentioned). Familiar with the meaning of front-end unit testing and common frameworks (Jest, etc.). Although it is not necessary to ask about the implementation in detail, it is beneficial to demonstrate engineering literacy.</li><li><strong>Modular Specification</strong>: Master the differences between mainstream JS modular solutions. <strong>CommonJS</strong> module is used in Node.js, and uses synchronous <code>require()</code> to load the module, which loads the module’s output object (value copy); <strong>ES6 Module</strong> standard determines module dependencies and output interfaces at compile time, supports <code>import/export</code>, is static analysis loading, and exports read-only references. Therefore, ES6 modules can perform Tree-shaking optimization of unused code. You can also learn about historical solutions such as AMD and CMD and why they are gradually replaced by ES6 modules (AMD asynchronous loading is suitable for browsers but the syntax is not intuitive, and the ES6 module syntax is more concise and unified).</li></ul><p>The above classification almost covers the high-frequency knowledge points of front-end interviews. It is recommended to go through the list one by one during the review, and check the unfamiliar concepts in time to deepen your understanding.</p><h2 id="2-Key-content-that-needs-to-be-mastered-in-depth-combined-with-preferences-and-background"><a href="#2-Key-content-that-needs-to-be-mastered-in-depth-combined-with-preferences-and-background" class="headerlink" title="2. Key content that needs to be mastered in depth (combined with preferences and background)"></a>2. Key content that needs to be mastered in depth (combined with preferences and background)</h2><p>Interview preparation time is limited, so you should focus on it. According to <strong>Kuaishou interview preferences</strong> and <strong>candidates’ own background</strong>, the following modules and knowledge are worth investing more effort in in-depth mastery:</p><ul><li><p><strong>React principles and framework comparison</strong>: As a candidate’s strength, React-related principles need to be mastered in depth so that you can show a deeper understanding than ordinary candidates in the interview. Kuaishou and other large companies often ask in-depth questions about framework implementation, such as virtual DOM, Diff algorithm, or ask you to compare the differences between React and Vue. Make full use of your practical experience with React and study its underlying mechanisms (such as Fiber architecture, synthetic events, etc.) in depth to make your answer more brilliant. Since you have not used Vue, you should also understand the basic concepts of Vue in advance to prevent comparison questions - the depth does not need to be too great, but you need to ensure that you do not leave a blank when answering.</p></li><li><p><strong>Performance optimization (especially the first screen and interactive performance)</strong>: This is an area where you have practical experience, and it is also an aspect that platforms with a huge number of users like Kuaishou attach great importance to. In the interview, you may be asked how to optimize a performance bottleneck scenario, such as how to improve the <strong>slow loading of the first screen</strong> or make a product smoother in a weak network environment. You should have a deep understanding of performance optimization techniques at all levels (loading, rendering, encoding, etc.) and be prepared to combine case studies with your own projects. Kuaishou directly asked candidates what performance optimizations they made in their mini-programs during the interview, which shows how much they value this. Make full use of your practice in performance tuning, sort out a set of systematic optimization ideas, and talk about it in the interview will be a big plus.</p></li><li><p><strong>Browser principles and JS basics</strong>: These are the foundation of front-end interviews, and often determine the interviewer’s evaluation of your depth and breadth. Interviews at large companies like to extend the basic concepts to ask tricky questions (for example, using examples to examine the event loop instead of asking about the concept directly). In view of this, you need to be familiar with the basics (event loop, scope closure, prototype chain, DOM/CSS mechanism, etc.) and understand them thoroughly. Combined with your full-stack background, you can have a deeper understanding of some browser mechanisms (such as the relationship between the rendering thread and the JS thread), which will make your answers more convincing. When reviewing, <strong>focus on understanding the principles</strong> instead of memorizing the conclusions, so that no matter how the interview changes, you can cope with it with ease.</p></li><li><p><strong>Security knowledge</strong>: You have practical development experience in security, which is your advantage. Front-end interviews at large companies often ask security questions such as XSS/CSRF prevention measures, and many fresh graduates are weak in this area. If you can give a <strong>rich and detailed answer</strong> (such as explaining output encoding, various means of defending CSRF and combining back-end verification mechanisms, etc.), it will surely impress the interviewer. Since you have a back-end development background, you can explain the security solution from a full-stack perspective (such as how the server cooperates with protection), reflecting a comprehensive security awareness. It is recommended to focus on memorizing the causes and defense strategies of common Web vulnerabilities, and appropriately demonstrate your security sensitivity in the interview.</p></li><li><p><strong>Engineering and project practice</strong>: Considering that your background involves back-end and deployment technologies such as Go and Docker, Kuaishou interviewers may be interested in your engineering thinking and full-stack capabilities. Although campus recruitment front-end positions do not necessarily test back-end knowledge in depth, <strong>front-end engineering</strong> is a common test point. You should have a deep understanding of the principles of the build tool chain (Webpack, Babel, etc.) to deal with difficult questions. For example, Kuaishou has interviewed questions about Babel transcoding process, custom ESLint plug-ins and other engineering-oriented questions. You can use your own learning and project experience to give in-depth answers to these questions. At the same time, you can prepare some insights on topics such as how to use Docker to deploy front-end applications and front-end and back-end collaboration optimization, and show your maturity in engineering during the free question session or resume discussion.</p></li></ul><p><strong>Focusing on the above points</strong> will maximize your advantages. In these two days, spend more time digging into the details of the above content and organizing the output framework. At the same time, you don’t need to make special preparations for <strong>algorithms and handwritten code</strong> questions (the requirements of the questions have been clearly stated that they will not be tested), and focus your energy on the knowledge section. For <strong>Vue framework details</strong>, you can just try them briefly and have a good idea of them: after all, it is difficult to master Vue from scratch in two days. It is better to use the time to strengthen React and common principles, and be prepared to show your <strong>willingness to quickly learn new frameworks</strong>.</p><h2 id="3-Review-order-and-time-arrangement-two-day-plan"><a href="#3-Review-order-and-time-arrangement-two-day-plan" class="headerlink" title="3. Review order and time arrangement (two-day plan)"></a>3. Review order and time arrangement (two-day plan)</h2><p><strong>Overall idea</strong>: First consolidate the foundation and then sprint to the key points, and allocate time reasonably to ensure breadth coverage while highlighting the depth of key points. In the only two days, divide each day into several time periods and review different modules alternately to maintain efficiency. The specific arrangement is as follows:</p><p><strong>Day 1 Morning: Basic consolidation (HTML/CSS & JavaScript)</strong><br>Use the clearest time in the morning of the first day to quickly review the basic knowledge of the front-end. First spend about 2 hours to sort out the <strong>HTML/CSS</strong> basics: review the box model, layout techniques, common style problems, etc. (You can quickly browse the relevant questions and answers by browsing the summary of front-end interview questions). Then spend about 2 hours to strengthen the <strong>JavaScript core</strong>: focus on high-frequency test points such as scope, closure, prototype chain, <code>this</code>, event loop, etc., and combine code snippets to deepen understanding. If you encounter vague concepts, check the MDN documents or notes in time to clarify the principles. This basic module review is not only a preparation for individual test points, but also a prerequisite for subsequent understanding of advanced topics (such as framework principles).</p><p><strong>Day 1 Afternoon: Framework Principles (React as the main, Vue as a side)</strong><br>In the afternoon, when you are energetic, focus on <strong>React working principles</strong>. Spend about 1 hour to sort out knowledge points such as React life cycle, state update mechanism, synthetic event model, etc. It is recommended to summarize while drawing a structure diagram (such as the React Fiber architecture diagram). Next, focus on <strong>Virtual DOM & Diff algorithm</strong> for about 1 hour: you can find information to read the outline of React Diff principle and practice the virtual DOM diff process on paper. Then spend about 0.5~1 hour to understand <strong>Vue core principles</strong>: focus on clarifying the implementation of responsive data binding and virtual DOM in Vue, and take a look at the name of Vue life cycle in case you are asked. Finally, leave about 0.5 hours <strong>Compare React and Vue</strong>: summarize a list of differences between the two (you can directly compare the similarities/differences sorted out before) so that the interview answers are organized. After completing this afternoon review, you will be confident in answering framework questions.</p><p><strong>Day 1 Evening: Network and Security</strong><br>At night, attention is slightly reduced, suitable for reading and memory review. First, spend about 1 hour browsing <strong>Computer Network</strong> Related knowledge: Focus on the key points of HTTP protocol (methods, status codes, caching mechanisms, HTTP2 features, etc.), and you can use notes or question banks to quickly test yourself in the form of QA. Some places that need to be remembered (such as the meaning of HTTP status codes) can be consolidated by quickly reciting + memorizing the key points. Next, spend about 1 hour to concentrate on studying <strong>Web Security</strong> Module: It is recommended to read the typical cases and protection solutions blogs of XSS and CSRF to deepen your impression, and then close the materials and try to repeat the complete attack process and defense measures by yourself. If you have extra time, you can also learn about common- <strong>Others</strong>: Vue2 is more declarative programming, while Vue3 begins to introduce a combinational API close to React’s Hooks idea; Vue has built-in two-way binding to facilitate form processing, while React defaults to a one-way data flow, and you need to write your own event processing to update the state. In general, both have their advantages and disadvantages, and you need to choose according to the scenario. When talking about it during the interview, you can first point out their common ideas, and then use the above differences to explain.</p><h3 id="7-Performance-optimization-2"><a href="#7-Performance-optimization-2" class="headerlink" title="7. Performance optimization"></a>7. Performance optimization</h3><ul><li><strong>Web page performance indicators</strong>: Understand the concepts of common page performance indicators such as first screen rendering time, white screen time, TTFB, FPS, etc., so that you can discuss performance experience with the interviewer. But more importantly, master the optimization method.</li><li><strong>Resource loading optimization</strong>: Master the <strong>image lazy loading</strong> principle (delayed loading of off-screen images, users scroll to the visible area and then set the real <code>src</code> to trigger loading) and implementation methods (such as <code><img></code> using <code>data-src</code> + listening to <code>scroll</code> events or IntersectionObserver). Understand <strong>code splitting</strong> and on-demand loading, and use Webpack and other methods to split bundles by route or component to reduce the size of first-screen resources.</li><li><strong>Function throttling and debounce</strong>: Understand the application of <strong>throttling</strong> and <strong>debounce</strong> technologies in the optimization of high-frequency events such as scrolling and input. Throttling allows a function to execute at a fixed frequency under continuous triggering (at most once in n seconds); debounce combines multiple triggers into the last execution (wait for n seconds after the trigger is completed). Be able to give examples of usage scenarios, such as throttling for scrolling event processing, debounce for input box search to prevent continuous requests, etc.</li><li><strong>Reduce reflow and redrawing</strong>: Optimize DOM operations to minimize the number and scope of Layout/Reflow. Specific measures include: avoid frequent direct style changes, prioritize batch changes or use <code>class</code> switching; avoid frequent insertion and deletion of nodes in the DOM tree. If necessary, you can first <code>display:none</code> the element (trigger a reflow first), and then display it after the operation is completed; use <code>transform</code> or <code>opacity</code> to trigger the synthesis layer for large animations to avoid repeated reflow; avoid using <code>table</code> layout, etc.</li><li><strong>Cache and resource optimization</strong>: use browser cache (strong cache/negotiation cache) to reduce requests; enable Gzip/Brotli compression to transmit resources; place commonly used static resources on CDN to increase access speed; use browser offline storage (such as Service Worker cache) to improve revisit performance, etc.</li><li><strong>Build package optimization</strong>: optimize front-end code performance through build tools. Typical methods include: <strong>Code compression obfuscation</strong> (reduce file size), <strong>Tree-Shaking</strong> (tree-shaking optimization deletes unreferenced code), <strong>SplitChunks</strong> split code, lazy loading by route, extracting public libraries, enabling package cache, etc. In addition, using production mode to build and remove development and debugging code, and properly configuring the optimization option of webpack are also common interview points.</li><li><strong>Performance monitoring</strong>: Familiar with basic performance monitoring methods, such as using Chrome DevTools Performance to record and analyze frame rate and call stack, and using Lighthouse for performance scoring. Although the interview may not ask about the use of tools in detail, it will be a plus if you can show your ability to monitor and locate performance problems.</li></ul><h3 id="8-Front-end-engineering-and-modularization-1"><a href="#8-Front-end-engineering-and-modularization-1" class="headerlink" title="8. Front-end engineering and modularization"></a>8. Front-end engineering and modularization</h3><ul><li><strong>Version control (Git)</strong>: Understand common Git commands (such as clone, branch, add, commit, push, etc.) and team collaboration processes. In particular, you need to master the difference between merge and rebase in the branch merge strategy: merge will generate a new merge commit and retain the historical fork of the branch; rebase will replay the branch commits sequentially at the top of the target branch without generating additional fork points. Large companies may pay attention to your understanding of team collaboration and code management.</li><li><strong>Building tools (Webpack)</strong>: Frequently tested Webpack principles and configurations. Need to know the difference between <strong>Loader</strong> and <strong>Plugin</strong>: Loader is essentially a file converter, used to process non-JS resources and convert them into modular JS; Plugin is hooked into the Webpack life cycle to extend Webpack functions, such as packaging optimization. Be familiar with several typical Loaders/Plugins (such as <code>babel-loader</code> converting ES6 to ES5, <code>file-loader</code> processing images, <code>HtmlWebpackPlugin</code> automatically generating HTML, etc.).</li><li><strong>Webpack hot update HMR</strong>: Understand the principle of Webpack hot module replacement (Hot Module Replacement). That is, in development mode, Webpack-dev-server establishes a WebSocket connection, and when it detects changes in the source code, it pushes the new module code to the browser through WebSocket and replaces the old module without refreshing the entire page. Can briefly describe the process and benefits of HMR (preserving application status and improving development efficiency).</li><li><strong>Babel Transpilation</strong>: Master the process of Babel converting ES6+ code to backward compatible JS. Including: Parsing – Parsing the source code into an abstract syntax tree (AST); Transforming – Transforming AST nodes according to the configured plugin presets (such as arrow functions to ordinary functions, etc.); Generating – Regenerate JS code based on the converted AST. This process reflects the compilation mechanism of front-end engineering, and senior interviews may ask in depth.</li><li><strong>Lint and Unit Testing</strong>: Understand code quality tools such as ESLint rule customization, and understand how to encapsulate custom ESLint plug-ins (know its basic mechanism of traversing AST, which can be briefly mentioned). Familiar with the meaning of front-end unit testing and common frameworks (Jest, etc.). Although it is not necessary to ask about the implementation in detail, it is beneficial to demonstrate engineering literacy.</li><li><strong>Modular Specification</strong>: Master the differences between mainstream JS modular solutions. <strong>CommonJS</strong> module is used in Node.js, and uses synchronous <code>require()</code> to load the module, which loads the module’s output object (value copy); <strong>ES6 Module</strong> standard determines module dependencies and output interfaces at compile time, supports <code>import/export</code>, is static analysis loading, and exports read-only references. Therefore, ES6 modules can perform Tree-shaking optimization of unused code. You can also learn about historical solutions such as AMD and CMD and why they are gradually replaced by ES6 modules (AMD asynchronous loading is suitable for browsers but the syntax is not intuitive, and the ES6 module syntax is more concise and unified).</li></ul><p>The above classification almost covers the high-frequency knowledge points of front-end interviews. It is recommended to go through the list one by one during the review, and check the unfamiliar concepts in time to deepen your understanding.</p><h2 id="2-Key-content-that-needs-to-be-mastered-in-depth-combined-with-preferences-and-background-1"><a href="#2-Key-content-that-needs-to-be-mastered-in-depth-combined-with-preferences-and-background-1" class="headerlink" title="2. Key content that needs to be mastered in depth (combined with preferences and background)"></a>2. Key content that needs to be mastered in depth (combined with preferences and background)</h2><p>Interview preparation time is limited, so you should focus on it. According to <strong>Kuaishou interview preferences</strong> and <strong>candidates’ own background</strong>, the following modules and knowledge are worth investing more effort in in-depth mastery:</p><ul><li><p><strong>React principles and framework comparison</strong>: As a candidate’s strength, React-related principles need to be mastered in depth so that you can show a deeper understanding than ordinary candidates in the interview. Kuaishou and other large companies often ask in-depth questions about framework implementation, such as virtual DOM, Diff algorithm, or ask you to compare the differences between React and Vue. Make full use of your practical experience with React and study its underlying mechanisms (such as Fiber architecture, synthetic events, etc.) in depth to make your answer more brilliant. Since you have not used Vue, you should also understand the basic concepts of Vue in advance to prevent comparison questions - the depth does not need to be too great, but you need to ensure that you do not leave a blank when answering.</p></li><li><p><strong>Performance optimization (especially the first screen and interactive performance)</strong>: This is an area where you have practical experience, and it is also an aspect that platforms with a huge number of users like Kuaishou attach great importance to. In the interview, you may be asked how to optimize a performance bottleneck scenario, such as how to improve the <strong>slow loading of the first screen</strong> or make a product smoother in a weak network environment. You should have a deep understanding of performance optimization techniques at all levels (loading, rendering, encoding, etc.) and be prepared to combine case studies with your own projects. Kuaishou directly asked candidates what performance optimizations they made in their mini-programs during the interview, which shows how much they value this. Make full use of your practice in performance tuning, sort out a set of systematic optimization ideas, and talk about it in the interview will be a big plus.</p></li><li><p><strong>Browser principles and JS basics</strong>: These are the foundation of front-end interviews, and often determine the interviewer’s evaluation of your depth and breadth. Interviews at large companies like to extend the basic concepts to ask tricky questions (for example, using examples to examine the event loop instead of asking about the concept directly). In view of this, you need to be familiar with the basics (event loop, scope closure, prototype chain, DOM/CSS mechanism, etc.) and understand them thoroughly. Combined with your full-stack background, you can have a deeper understanding of some browser mechanisms (such as the relationship between the rendering thread and the JS thread), which will make your answers more convincing. When reviewing, <strong>focus on understanding the principles</strong> instead of memorizing the conclusions, so that no matter how the interview changes, you can cope with it with ease.</p></li><li><p><strong>Security knowledge</strong>: You have practical development experience in security, which is your advantage. Front-end interviews at large companies often ask security questions such as XSS/CSRF prevention measures, and many fresh graduates are weak in this area. If you can give a <strong>rich and detailed answer</strong> (such as explaining output encoding, various means of defending CSRF and combining back-end verification mechanisms, etc.), it will surely impress the interviewer. Since you have a back-end development background, you can explain the security solution from a full-stack perspective (such as how the server cooperates with protection), reflecting a comprehensive security awareness. It is recommended to focus on memorizing the causes and defense strategies of common Web vulnerabilities, and appropriately demonstrate your security sensitivity in the interview.</p></li><li><p><strong>Engineering and project practice</strong>: Considering that your background involves back-end and deployment technologies such as Go and Docker, Kuaishou interviewers may be interested in your engineering thinking and full-stack capabilities. Although campus recruitment front-end positions do not necessarily test back-end knowledge in depth, <strong>front-end engineering</strong> is a common test point. You should have a deep understanding of the principles of the build tool chain (Webpack, Babel, etc.) to deal with difficult questions. For example, Kuaishou has interviewed questions about Babel transcoding process, custom ESLint plug-ins and other engineering-oriented questions. You can use your own learning and project experience to give in-depth answers to these questions. At the same time, you can prepare some insights on topics such as how to use Docker to deploy front-end applications and front-end and back-end collaboration optimization, and show your maturity in engineering during the free question session or resume discussion.</p></li></ul><p><strong>Focusing on the above points</strong> will maximize your advantages. In these two days, spend more time digging into the details of the above content and organizing the output framework. At the same time, you don’t need to make special preparations for <strong>algorithms and handwritten code</strong> questions (the requirements of the questions have been clearly stated that they will not be tested), and focus your energy on the knowledge section. For <strong>Vue framework details</strong>, you can just try them briefly and have a good idea of them: after all, it is difficult to master Vue from scratch in two days. It is better to use the time to strengthen React and common principles, and be prepared to show your <strong>willingness to quickly learn new frameworks</strong>.</p><h2 id="3-Review-order-and-time-arrangement-two-day-plan-1"><a href="#3-Review-order-and-time-arrangement-two-day-plan-1" class="headerlink" title="3. Review order and time arrangement (two-day plan)"></a>3. Review order and time arrangement (two-day plan)</h2><p><strong>Overall idea</strong>: First consolidate the foundation and then sprint to the key points, and allocate time reasonably to ensure breadth coverage while highlighting the depth of key points. In the only two days, divide each day into several time periods and review different modules alternately to maintain efficiency. The specific arrangement is as follows:</p><p><strong>Day 1 Morning: Basic consolidation (HTML/CSS & JavaScript)</strong><br>Use the clearest time in the morning of the first day to quickly review the basic knowledge of the front-end. First spend about 2 hours to sort out the <strong>HTML/CSS</strong> basics: review the box model, layout techniques, common style problems, etc. (You can quickly browse the relevant questions and answers by browsing the summary of front-end interview questions). Then spend about 2 hours to strengthen the <strong>JavaScript core</strong>: focus on high-frequency test points such as scope, closure, prototype chain, <code>this</code>, event loop, etc., and combine code snippets to deepen understanding. If you encounter vague concepts, check the MDN documents or notes in time to clarify the principles. This basic module review is not only a preparation for individual test points, but also a prerequisite for subsequent understanding of advanced topics (such as framework principles).</p><p><strong>Day 1 Afternoon: Framework Principles (React as the main, Vue as a side)</strong><br>In the afternoon, when you are energetic, focus on <strong>React working principles</strong>. Spend about 1 hour to sort out knowledge points such as React life cycle, state update mechanism, synthetic event model, etc. It is recommended to summarize while drawing a structure diagram (such as the React Fiber architecture diagram). Next, focus on <strong>Virtual DOM & Diff algorithm</strong> for about 1 hour: you can find information to read the outline of React Diff principle and practice the virtual DOM diff process on paper. Then spend about 0.5~1 hour to understand <strong>Vue core principles</strong>: focus on clarifying the implementation of responsive data binding and virtual DOM in Vue, and take a look at the name of Vue life cycle in case you are asked. Finally, leave about 0.5 hours <strong>Compare React and Vue</strong>: summarize a list of differences between the two (you can directly compare the similarities/differences sorted out before) so that the interview answers are organized. After completing this afternoon review, you will be confident in answering framework questions.</p><p><strong>Day 1 Evening: Network and Security</strong><br>At night, attention is slightly reduced, suitable for reading and memory review. First, spend about 1 hour browsing <strong>Computer Network</strong> Related knowledge: Focus on the key points of HTTP protocol (methods, status codes, caching mechanisms, HTTP2 features, etc.), and you can use notes or question banks to quickly test yourself in the form of QA. Some places that need to be remembered (such as the meaning of HTTP status codes) can be consolidated by quickly reciting + memorizing the key points. Next, spend about 1 hour to concentrate on studying <strong>Web Security</strong> Module: It is recommended to read the typical cases and protection solutions blogs of XSS and CSRF to deepen your impression, and then close the materials and try to repeat the complete attack process and defense measures by yourself. If you have extra time, you can also learn about common</p><h2 id="一、重要知识点分类及重点清单"><a href="#一、重要知识点分类及重点清单" class="headerlink" title="一、重要知识点分类及重点清单"></a>一、重要知识点分类及重点清单</h2><p><strong>建议将知识梳理为以下几个模块</strong>,每个模块列出常见的“八股文”考点以备速览复习:</p><h3 id="1-HTML-与-CSS-基础"><a href="#1-HTML-与-CSS-基础" class="headerlink" title="1. HTML 与 CSS 基础"></a>1. HTML 与 CSS 基础</h3><ul><li><strong>CSS盒模型</strong>:了解盒子的组成(内容content、内边距padding、边框border、外边距margin)及其对元素尺寸的影响。 </li><li><strong>CSS选择器优先级</strong>:掌握样式冲突时优先级计算规则(继承 < 元素内联样式 < <code>!important</code> 等)。 </li><li><strong>元素水平垂直居中</strong>:熟悉多种居中布局方法,如利用定位 + <code>margin</code>、定位 + <code>transform</code>,或使用弹性盒(Flexbox)等实现居中。 </li><li><strong>重排与重绘</strong>:理解重排(回流)和重绘的区别及触发条件。重排是布局改变(如尺寸、位置变化)引起,需要重新计算布局;重绘是外观样式改变但布局未变,只重新绘制像素。</li></ul><h3 id="2-JavaScript-与-ES6"><a href="#2-JavaScript-与-ES6" class="headerlink" title="2. JavaScript 与 ES6"></a>2. JavaScript 与 ES6</h3><ul><li><strong>原型与原型链</strong>:理解 JavaScript 原型链实现继承的机制。原型本质是一个对象,用于共享属性和方法;实例通过 <code>__proto__</code> 链接至构造函数的 <code>prototype</code> 实现属性查找。 </li><li><strong>闭包</strong>:掌握闭包概念及作用。闭包是指能够访问另一个函数作用域中变量的函数,常通过在一个函数内部创建另一个函数产生。闭包可用于封装私有变量、避免全局变量污染等。 </li><li><strong><code>this</code> 绑定</strong>:搞清 <code>this</code> 在不同场景下的指向规则(函数直接调用时指向全局对象;方法调用指向调用它的对象;构造函数调用指向新实例;<code>call/apply</code> 可以显式改变 <code>this</code>)。注意箭头函数没有自身 <code>this</code>,会捕获外层 <code>this</code>。 </li><li><strong>事件循环与异步</strong>:理解浏览器的 JavaScript <strong>事件循环 (Event Loop)</strong> 机制,区分宏任务(macrotask)和微任务(microtask)。JavaScript 采用单线程运行,通过事件循环不断检查并执行任务队列中的任务。掌握如 <code>setTimeout</code>、<code>Promise</code>、<code>async/await</code> 等异步机制的执行顺序。 </li><li><strong>ES6+ 新特性</strong>:熟悉常见ES6/ES7特性及用法,例如 <code>let</code>/<code>const</code> 的作用域区别、箭头函数绑定词法<code>this</code>、<code>Set/Map</code>容器类型、<code>Promise</code> 及 <code>async/await</code> 实现异步、类(Class)语法糖及继承等。这些特性往往是面试高频话题,应能说明其用途和优劣。</li></ul><h3 id="3-浏览器原理"><a href="#3-浏览器原理" class="headerlink" title="3. 浏览器原理"></a>3. 浏览器原理</h3><ul><li><strong>浏览器渲染流程</strong>:理解从输入HTML到页面呈现的基本过程:构建DOM树 -> 构建CSSOM树 -> 合并生成渲染树 -> 布局(Reflow)-> 绘制(Paint)。知道CSS如何影响渲染(如外部CSS加载会阻塞渲染树构建)等。 </li><li><strong>浏览器多进程架构</strong>:了解现代浏览器的进程划分(如浏览器主进程、渲染进程、网络进程等)以及<strong>进程</strong>和<strong>线程</strong>的区别。进程有独立内存空间,崩溃互不影响;线程是进程内执行单元,共享内存。理解Chrome浏览器中渲染进程是多线程的(包含GUI渲染线程、JS引擎线程等)。 </li><li><strong>DOM 事件机制</strong>:掌握浏览器事件流的三个阶段:捕获 → 目标 → 冒泡。事件捕获从祖先节点向下传播,事件冒泡则从目标向上传播。了解如何使用<code>addEventListener</code>的第三个参数控制绑定阶段,以及使用<code>stopPropagation()</code>阻止冒泡。 </li><li><strong>脚本加载策略</strong>:理解<code><script></code>标签中 <code>async</code> 和 <code>defer</code> 属性的区别:没有属性时浏览器同步解析并执行脚本;<code>async</code>表示脚本异步下载且下载完成后立即执行(不保证按顺序);<code>defer</code>表示脚本异步下载但延迟到HTML解析完成后按顺序执行。 </li><li><strong>浏览器存储</strong>:了解几种<strong>前端存储</strong>方式:Cookie、<code>localStorage</code>、<code>sessionStorage</code>、<code>IndexedDB</code> 等区别。例如,Cookie会被自动附带在请求中、容量小多用于保存会话标识,<code>localStorage</code>容量较大且持久存在,<code>sessionStorage</code>在会话结束后清空等。 </li><li><strong>浏览器缓存机制</strong>:掌握HTTP缓存策略,如<strong>强缓存</strong>(Expires/Cache-Control)和<strong>协商缓存</strong>(Last-Modified/Etag)的原理。能解释浏览器如何判断缓存有效以及返回304的过程。</li></ul><h3 id="4-网络与协议"><a href="#4-网络与协议" class="headerlink" title="4. 网络与协议"></a>4. 网络与协议</h3><ul><li><strong>GET 和 POST 区别</strong>:明确 HTTP GET 与 POST 在语义和实现上的差异。例如:GET一般用于获取资源,参数附在URL且有长度限制;POST用于提交数据,放在请求体,无长度限制;GET请求可被浏览器缓存而POST不会自动缓存;安全性上POST相对更安全一点等。 </li><li><strong>HTTP1.1 和 HTTP2</strong>:了解HTTP/1.1相对于HTTP/2的主要改进点。如HTTP/2采用二进制分帧传输、支持<strong>多路复用</strong>(一个连接并发多个请求,无队头阻塞HTTP层,但TCP层队头阻塞仍存在)、头部压缩等。知道HTTP/3基于QUIC的进一步优化(可简单提及)。 </li><li><strong>网络通信基础</strong>:掌握TCP三次握手、四次挥手的基本过程,了解TLS/SSL握手在HTTPS中的作用。虽非纯前端范畴,但面试可能涉及简单问答。 </li><li><strong>其他协议/机制</strong>:了解<strong>WebSocket</strong>相对HTTP的区别(全双工通信、需握手升级协议等)和常见应用场景。熟悉<strong>HTTP状态码</strong>含义(尤其2xx、3xx重定向、4xx客户端错误如401/403/404、5xx服务器错误)。这些有备无患,回答HTTP相关问题时可顺带提及。 </li><li><strong>请求过程和优化</strong>:熟悉从浏览器地址栏输入URL到页面加载的全过程,包括DNS解析、TCP连接、发送请求、接受响应、浏览器渲染的各个阶段。能够结合缓存、CDN等说明提高网络加载性能的方法(如启用CDN就近访问,减少请求体积等)。</li></ul><h3 id="5-安全"><a href="#5-安全" class="headerlink" title="5. 安全"></a>5. 安全</h3><ul><li><strong>XSS 跨站脚本攻击</strong>:理解 XSS 的原理——攻击者向目标网站注入恶意脚本代码,使之在其他用户浏览器上执行,从而窃取用户数据(如Cookie)等。掌握常见防范措施:<strong>输入过滤和转义</strong>(对用户输入进行HTML转义过滤特殊字符)、<strong>内容安全策略(CSP)</strong>、敏感Cookie设置<code>HttpOnly</code>防止脚本读取等。 </li><li><strong>CSRF 跨站请求伪造</strong>:了解 CSRF 的攻击机制——利用用户已登录状态,在用户不知情情况下冒用其身份发送恶意请求。防御方法包括:请求附加**防伪随机令牌(token)**并验证、使用<code>SameSite</code>严格的Cookie、关键操作增加验证码确认等。 </li><li><strong>同源策略与跨域</strong>:理解浏览器<strong>同源策略</strong>(Same-Origin Policy)对JavaScript的限制,知道同源指协议、域名、端口均相同。掌握几种<strong>跨域解决方案</strong>:如服务端设置 <strong>CORS</strong> 响应头允许跨域资源共享、JSONP 利用 <code><script></code> 不受同源限制(仅支持GET)、以及反向代理转发等机制。 </li><li><strong>其他安全</strong>:了解<strong>点击劫持</strong>(ClickJacking)防护(通过<code>X-Frame-Options</code>禁用iframe嵌套),以及前端如何防范<strong>恶意输入</strong>导致的崩溃(如正则拒绝服务ReDoS)等。安全类问题回答时可以结合实际项目中遇到的安全加固措施来体现经验。</li></ul><h3 id="6-前端框架原理(React-为主)"><a href="#6-前端框架原理(React-为主)" class="headerlink" title="6. 前端框架原理(React 为主)"></a>6. 前端框架原理(React 为主)</h3><ul><li><p><strong>Virtual DOM 与 Diff</strong>:理解虚拟DOM的作用:在JS和真实DOM之间加了一层抽象的DOM树缓存,通过Diff算法比较新旧虚拟DOM高效更新真实DOM,避免不必要的DOM操作。知道React的Diff策略(同层对比、列表节点需唯一<code>key</code>等)和其带来的性能提升。 </p></li><li><p><strong>React Fiber 架构</strong>:掌握React16引入Fiber的原因和原理。React15的协调器采用递归处理组件树,更新不可中断,长时间更新会阻塞UI。Fiber将更新任务拆分为可中断的小单元(链表形式),利用浏览器空闲时间执行,避免长任务阻塞渲染,实现<strong>可中断的调度与渲染</strong>。 </p></li><li><p><strong>React 生命周期</strong>:熟悉React类组件生命周期各阶段(挂载Mounting -> 更新Updating -> 卸载Unmounting)及主要生命周期方法。如<code>componentDidMount/Update/WillUnmount</code>等,了解其调用顺序和典型用途。同时了解函数组件的Hooks等价写法(如<code>useEffect</code>对应部分生命周期)。 </p></li><li><p><strong>合成事件机制</strong>:了解React合成事件模型的工作方式。React并没有将事件处理器直接绑定在DOM节点上,而是采用事件委托机制**统一绑定在根节点(document)**上,这样可以提高性能并实现跨浏览器一致的事件行为。明晰这一机制与原生DOM事件的区别,如事件池、syntheticEvent对象等。 </p></li><li><p><strong>错误边界</strong>:知道React中捕获错误的方式,例如使用<code>componentDidCatch</code>或<code>getDerivedStateFromError</code>定义<strong>Error Boundary</strong>组件来统一处理子组件的运行时错误,以防止错误导致整个应用崩溃(这一点可以简单提及)。 </p></li><li><p><strong>Vue 基础了解</strong>:尽管未实际使用Vue,但应<strong>粗略了解Vue的核心原理</strong>以应对比较类问题。如:Vue通过数据劫持实现响应式(Vue2用<code>Object.defineProperty</code>,Vue3用<code>Proxy</code>);Vue模板会在编译阶段解析指令和插值,生成虚拟DOM并更新;Vue的双向数据绑定(v-model)和React单向数据流的区别等。 </p></li><li><p><strong>React vs Vue</strong>:能比较两大框架的<strong>相同点</strong>和<strong>差异</strong>。相同点:二者都采用组件化、数据驱动视图,都使用虚拟DOM+Diff算法优化更新,也都有配套的路由和状态管理方案。差异: </p><ul><li><strong>核心理念</strong>:Vue是渐进式框架,核心是响应式的MVVM数据绑定;React是用于构建UI的库,强调单向数据流和函数式 UI。 </li><li><strong>语法风格</strong>:Vue推荐SFC单文件组件(<code>template</code>+script+style,直观易上手),也支持指令语法和JSX;React强制使用JSX,将HTML和CSS以JSX/Inline Style写在JavaScript中(“All in JS”)。 </li><li><strong>数据更新机制</strong>:Vue自动追踪依赖并在数据变化时高效更新DOM(大量内置优化和语法糖),开发者无需手动处理;React需通过<code>setState</code>触发更新,可能需要应对性能问题(例如手动使用<code>shouldComponentUpdate</code>或Memo来优化),很多功能(如全局状态管理)依赖社区库提供。 </li><li><strong>其他</strong>:Vue2偏声明式编程,Vue3开始引入组合式API接近React的Hooks思想;Vue内置双向绑定方便表单处理,而React默认单向数据流,需要自行编写事件处理来更新状态等。总体来说,二者各有优劣,需根据场景选择。面试中谈及时,可以先指出它们的共同理念,再举上述差异点加以阐述。</li></ul></li></ul><h3 id="7-性能优化"><a href="#7-性能优化" class="headerlink" title="7. 性能优化"></a>7. 性能优化</h3><ul><li><strong>网页性能指标</strong>:了解页面性能常用指标如首屏渲染时间、白屏时间、TTFB、FPS等概念,便于和面试官讨论性能体验。但更重要是掌握优化方法。 </li><li><strong>资源加载优化</strong>:掌握<strong>图片懒加载</strong>原理(延迟加载屏幕外图片,用户滚动到可视区域再设置真实<code>src</code>触发加载)和实现方式(如<code><img></code>使用<code>data-src</code>+监听<code>scroll</code>事件或IntersectionObserver)。了解<strong>代码分割</strong>和按需加载,通过Webpack等实现按路由或组件拆分bundle,减少首屏资源体积。 </li><li><strong>函数节流与防抖</strong>:理解<strong>节流 (throttle)</strong> 和<strong>防抖 (debounce)</strong> 技术在滚动、输入等高频事件优化中的应用。节流是让函数在连续触发情况下以固定频率执行(n秒至多执行一次);防抖是将多次触发合并为最后一次执行(等待触发完n秒后执行)。能举例说明使用场景,如节流用于滚动滚动事件处理、防抖用于输入框搜索防止连续请求等。 </li><li><strong>减少重排重绘</strong>:优化DOM操作,尽量减少Layout/Reflow次数和影响范围。具体措施如:避免直接频繁修改样式,优先批量修改或使用<code>class</code>切换;避免在DOM树中频繁插入删除节点,必要时可以先将元素<code>display:none</code>(先触发一次重排),操作完成后再显示;对大型动画使用<code>transform</code>或<code>opacity</code>触发合成层,避免反复回流;避免使用<code>table</code>布局等。 </li><li><strong>缓存和资源优化</strong>:利用浏览器缓存(强缓存/协商缓存)减少请求;开启 Gzip/ Brotli 压缩传输资源;将常用静态资源放置CDN提高访问速度;使用浏览器离线存储(如Service Worker缓存)提升重访性能等。 </li><li><strong>构建打包优化</strong>:通过构建工具优化前端代码性能。典型方法包括:<strong>代码压缩混淆</strong>(减小文件体积)、<strong>Tree-Shaking</strong>(摇树优化删除未引用代码)、<strong>SplitChunks</strong>拆分代码、按路由懒加载、提取公共库、开启打包缓存等。另外,利用生产模式构建去除开发调试代码,合理配置<code>webpack</code>的<code>optimization</code>选项等也是常见面试点。 </li><li><strong>性能监测</strong>:熟悉基本性能监测手段,如使用Chrome DevTools Performance记录分析帧率、调用栈,用Lighthouse进行性能评分等。虽然面试不一定细问工具使用,但体现出对性能问题的监测和定位思路会有加分。</li></ul><h3 id="8-前端工程化与模块化"><a href="#8-前端工程化与模块化" class="headerlink" title="8. 前端工程化与模块化"></a>8. 前端工程化与模块化</h3><ul><li><strong>版本控制 (Git)</strong>:了解常用的 Git 命令(如<code>clone</code>、<code>branch</code>、<code>add</code>、<code>commit</code>、<code>push</code>等)和团队协作流程。尤其需掌握<strong>分支合并策略</strong>中 <code>merge</code> 和 <code>rebase</code> 的区别:<code>merge</code>会产生一次新的合并提交,保留分支的历史分叉;<code>rebase</code>则将分支提交在目标分支顶端顺序重放,不产生额外的分叉点。大厂可能关注你对团队协作和代码管理的理解。 </li><li><strong>构建工具 (Webpack)</strong>:常考 Webpack 原理及配置。需要清楚 <strong>Loader</strong> 和 <strong>Plugin</strong> 的区别:Loader本质是文件转换器,用于处理非JS资源,将其转为可模块化JS;Plugin则是在Webpack运行生命周期中挂钩执行,扩展Webpack功能,如打包优化等。熟悉几个典型Loader/Plugin(如<code>babel-loader</code>将ES6转ES5、<code>file-loader</code>处理图片、<code>HtmlWebpackPlugin</code>自动生成HTML等)。 </li><li><strong>Webpack 热更新 HMR</strong>:了解Webpack热模块替换(Hot Module Replacement)的原理。即在开发模式下,Webpack-dev-server建立WebSocket连接,检测到源码变动时,将新的模块代码通过WebSocket推送到浏览器并替换旧模块,而不刷新整个页面。能简单描述HMR的流程和好处(保留应用状态、提高开发效率)。 </li><li><strong>Babel 转译</strong>:掌握 Babel 将ES6+代码转换为向后兼容JS的流程。包括:解析(Parsing)–将源码解析成抽象语法树(AST);转换(Transforming)–按照配置的插件预设对AST节点进行变换(比如箭头函数转普通函数等);生成(Generating)–根据转换后的AST重新生成JS代码。这一流程体现前端工程的编译机制,高级面试有可能深入问到。 </li><li><strong>Lint与单测</strong>:了解代码质量工具如ESLint规则定制,理解如何封装自定义ESLint插件(知道其遍历AST的基本机制,可简单提及)。熟悉前端单元测试的意义和常用框架(Jest等),虽不一定细问实现,但展示工程化素养有利。 </li><li><strong>模块化规范</strong>:掌握主流JS模块化方案的区别。<strong>CommonJS</strong>模块用于Node.js,采用同步<code>require()</code>加载模块,加载的是模块的输出对象(值拷贝);<strong>ES6 Module</strong>标准在编译时确定模块依赖与输出接口,支持<code>import/export</code>,是静态分析加载,导出的是只读引用。因此ES6模块可以进行Tree-shaking优化未使用代码。还可了解AMD、CMD等历史方案及它们为何逐渐被ES6模块取代(AMD异步加载适合浏览器但语法不直观,ES6模块语法更简洁统一)。</li></ul><p>以上分类几乎涵盖了前端面试高频知识点。建议在复习中对照清单逐一过一遍,对于不熟悉的概念及时查阅加深理解。</p><h2 id="二、需要深入掌握的重点内容(结合偏好与背景)"><a href="#二、需要深入掌握的重点内容(结合偏好与背景)" class="headerlink" title="二、需要深入掌握的重点内容(结合偏好与背景)"></a>二、需要深入掌握的重点内容(结合偏好与背景)</h2><p>面试准备时间有限,应有所侧重。根据<strong>快手面试偏好</strong>和<strong>候选人自身背景</strong>,以下几个模块和知识值得投入更多精力深度掌握:</p><ul><li><p><strong>React 原理及框架比较</strong>:作为候选人的强项,React相关原理需深入掌握,以便在面试中展现出比一般候选人更深的理解。快手等大厂常会深入追问框架实现,比如虚拟DOM、Diff算法或让你对比React和Vue的区别。充分利用你对React的实践经验,深入研究其底层机制(如Fiber架构、合成事件等)能让你的回答更有亮点。由于你未使用过Vue,也应提前了解Vue的基本理念以防比较类问题——深度不必过大,但需保证回答时不至于一片空白。</p></li><li><p><strong>性能优化(尤其是首屏和交互性能)</strong>:这是你有实际经验的领域,也是快手这样用户量巨大的平台非常看重的方面。面试中很可能被问到如何优化某个性能瓶颈场景,例如如何改善<strong>首屏加载过慢</strong>的问题或者让某产品在弱网环境下更流畅。你应当深入掌握各层面的性能优化技巧(加载、渲染、编码等)并准备好结合自己项目的案例说明。快手面试中曾直接询问候选人在小程序中做了哪些性能优化,可见对此的重视。充分利用你在性能调优上的实践,整理出一套系统的优化思路,在面试时娓娓道来将非常加分。</p></li><li><p><strong>浏览器原理与 JS 基础</strong>:这些是前端面试的地基,往往决定了面试官对你深度和广度的评价。大厂面试喜欢从基础概念引申出有坑的提问方式(例如用实例考察事件循环而非直接问概念)。鉴于此,你需要对基础知识(事件循环、作用域闭包、原型链、DOM/CSS机制等)烂熟于心并融会贯通。结合你的全栈背景,可以更深入理解一些浏览器机制(如渲染线程与JS线程的关系),这会让你的回答更具说服力。在复习时<strong>着重理解原理</strong>而非死记结论,这样无论面试怎么变形问,你都能应对自如。</p></li><li><p><strong>安全知识</strong>:你在安全方面有实际开发经验,这是你的优势领域。大厂前端面试经常会问到XSS/CSRF的防范措施等安全问题,而许多应届生在这方面比较薄弱。如果你能够给出<strong>丰富且细致的回答</strong>(例如说明输出编码、防御CSRF的多种手段并结合后端验证机制等)势必让面试官眼前一亮。由于你有后端开发背景,可以从全栈视角阐述安全方案(例如服务端如何配合防护),体现出全面的安全意识。建议重点熟记常见Web漏洞的成因及防御策略,在面试中适当展现你的安全敏感度。</p></li><li><p><strong>工程化与项目实践</strong>:考虑到你的背景涉及Go、Docker等后端和部署技术,快手面试官可能会对你工程化思维和全栈能力感兴趣。虽然校招前端岗位不一定深入考察后端知识,但<strong>前端工程化</strong>是常考点,你应深入理解构建工具链原理(Webpack、Babel 等)以应对高难度提问。例如快手有面试过 Babel 转码流程、自定义 ESLint 插件等偏工程化的问题,你可以利用自己的学习和项目经验,在这些问题上给出有深度的回答。同时,你可以准备一些关于如何利用Docker部署前端应用、前后端协作优化等话题的见解,在面试自由提问环节或简历详聊时展现你工程化方面的成熟度。</p></li></ul><p><strong>聚焦上述重点</strong>将使你的优势最大化。在这两天里,对以上内容多花时间深挖细节、整理输出框架。同时,对于<strong>算法和手写代码</strong>类题目可以不做特别准备(题目要求已明确不考),把精力专注在知识版块上。对于<strong>Vue框架细节</strong>则可浅尝辄止,做到心中有数即可:毕竟两天很难从零精通Vue,不如把时间用于强化React和共通原理,并准备好说明<strong>愿意快速学习新框架</strong>的态度即可。</p><h2 id="三、复习顺序与时间安排(两天规划)"><a href="#三、复习顺序与时间安排(两天规划)" class="headerlink" title="三、复习顺序与时间安排(两天规划)"></a>三、复习顺序与时间安排(两天规划)</h2><p><strong>总体思路</strong>:先夯实基础再冲刺重点,合理分配时间,以确保广度覆盖的同时突出重点深度。在仅有的两天内,每天划分几个时段,交替复习不同模块以保持效率。具体安排如下:</p><p><strong>Day 1 上午:基础巩固(HTML/CSS & JavaScript)</strong><br>利用第一天清晨头脑最清醒的时段,快速复习前端基础知识。先花约2小时梳理 <strong>HTML/CSS</strong> 基础:回顾盒模型、布局技巧、常见样式问题等(可通过浏览前端面试题总结快速浏览相关问答)。然后用约2小时强化 <strong>JavaScript核心</strong>:专注作用域、闭包、原型链、<code>this</code>、事件循环等高频考点,结合代码片段加深理解。如果遇到模糊的概念,及时查MDN文档或笔记搞清原理。这个基础模块复习既是单独考点准备,也是后续理解高级专题(比如框架原理)的前提。</p><p><strong>Day 1 下午:框架原理攻坚(React 为主,兼顾 Vue)</strong><br>下午精力充沛时段,重点突破 <strong>React 工作原理</strong>。花约1小时整理React生命周期、状态更新机制、合成事件模型等知识点,建议边画结构图边总结(如React Fiber架构示意)。接下来约1小时专攻 <strong>Virtual DOM & Diff算法</strong>:可以找资料阅读React Diff原理概要并在纸上演练一次虚拟DOM diff过程。然后用约0.5~1小时了解 <strong>Vue核心原理</strong>:重点弄清响应式数据绑定和虚拟DOM在Vue中的实现,顺带看看Vue的生命周期名称,以防被问及。最后留出约0.5小时<strong>对比React和Vue</strong>:总结一份两者区别的清单(可以直接对照之前整理的相同/不同点),以便面试回答有条理。下午这段复习完成后,框架类问题你将胸有成竹。</p><p><strong>Day 1 晚上:网络与安全</strong><br>晚上注意力稍下降,适合阅读和记忆类复习。首先用约1小时浏览 <strong>计算机网络</strong> 相关知识:重点看HTTP协议要点(方法、状态码、缓存机制、HTTP2特性等),可以通过笔记或题库快速QA形式自测。一些需要记忆的地方(如HTTP状态码的意义)可以采取快速背诵+默写要点的方式巩固。接下来用约1小时集中学习 <strong>Web安全</strong> 模块:建议阅读XSS和CSRF的典型案例和防护方案博客,加深印象,然后合上资料尝试自己复述完整的攻击过程和防御措施。如果时间富余,也可以了解下常见浏览器安全策略(如同源策略、CORS原理)等。<strong>Day1</strong>晚上结束前,可简单回顾一下当天内容,加深记忆的同时列出尚存疑惑的点,准备第二天解决。</p><p><strong>Day 2 上午:性能优化专项</strong><br>第二天早上精力恢复,投入到 <strong>性能优化</strong> 模块的复习。用约1小时学习 <strong>页面加载优化</strong>:包括资源打包优化策略(文件拆分、懒加载)、缓存利用等,可通过阅读性能优化最佳实践文章获取要点,并对照自己项目看用了哪些手段。然后用约1小时复习 <strong>渲染性能优化</strong>:重点关注如何减少重排重绘、提升动画流畅度等,必要时把浏览器渲染原理再过一遍以理解优化背后的原因。接下来约0.5小时复习 <strong>算法优化和内存优化</strong>(虽不考算法题,但理解DOM操作耗时、JS大数据处理优化如Web Worker等,可防面试讨论到相关场景)。最后留约0.5小时,<strong>整理一套性能优化方案清单</strong>:按加载优化、渲染优化、代码优化分类写下关键词和措施。这套清单既是知识点总结,也可在面试问到性能时作为答题提纲瞬时调用。</p><p><strong>Day 2 中午/下午前段:工程化与模块化</strong><br>利用中午或下午早些时候的时间段(约1.5小时),复习 <strong>前端工程化</strong> 相关内容。首先回顾Webpack的核心概念和常见配置项,着重理解Loader/Plugin机制和构建流程,可结合网上的Webpack面试题整理快速浏览问答。然后花0.5小时看 <strong>Babel/Polyfill</strong> 相关知识,确保能解释 Babel 转码流程和常用的转译插件。接下来0.5小时熟悉 <strong>Git流程和工具</strong>:重点看团队协作中的分支管理、多人冲突解决等,理清<code>rebase</code>和<code>merge</code>区别以及语义化提交等概念,以防面试官顺带提及。再用0.5小时回顾 <strong>模块化演进</strong>:将CommonJS、ES6 Module差异点认真看一遍,记忆关键区别(同步/异步、值拷贝/引用等),想象如果被问到如何回答简练。经过这一中段时间,你对工程化的知识会成体系,不至于在相关问题上语焉不详。</p><p><strong>Day 2 下午后段:综合串讲与模拟</strong><br>在最后半天里,进行综合冲刺和查漏补缺。首先用<strong>约1小时</strong>时间快速串讲之前所有笔记:可以尝试闭卷回忆每个模块的要点,然后对照清单补充遗忘处。这种<strong>主动回忆</strong>有助于将知识从短期记忆转为长期记忆,便于第二天面试调用。接着,用<strong>约1小时</strong>进行<strong>模拟问答</strong>练习:可以找到一套前端八股文题库,随机抽取问题,快速在脑中组织答案并口述出来。这一步非常重要,它能暴露出哪些知识你虽然看了但讲不出来。对于发现的薄弱点,立即翻看资料再次理解,确保面试时能流畅表述。最后<strong>半小时左右</strong>,浏览<strong>常见面试总结</strong>博客或题单,获取一些<strong>流行高频题</strong>的信息(例如最近流行问AST的可以瞄一眼,但不要深陷新知识),做到心中有数。收尾时调整心态,整理好纸质/脑图版的知识框架,至此你已经最大程度地覆盖了面试知识点。晚上尽量保证休息,为面试保持良好精神状态。</p><p><em>两天的紧凑复习后,你应该对核心知识了然于胸。面试中若遇到没准备到的问题,也不必紧张,尽量根据相关基础知识现场分析应答。通过上述计划的高效复习,你将以更沉稳自信的姿态迎接快手前端面试。</em> </p><h2 id="四、参考资料"><a href="#四、参考资料" class="headerlink" title="四、参考资料"></a>四、参考资料</h2><p>在复习过程中,可借助一些优质题库和博文来高效获取要点知识和典型问答。推荐参考以下资源:</p><ul><li><p><strong>GitHub仓库:wangwenjie1314/webQd</strong> – <em>前端高频面试题合集</em>,按照模块(HTML&CSS、JS、Vue、React、工程化、网络等)整理了2024年最新常考知识要点。该仓库汇总了掘金优秀文章和网友面经,是刷题背题的极佳索引。 </p></li><li><p><strong>稀土掘金「前端八股文」系列</strong> – <em>作者wakaka378等的专题文章</em>,涵盖浏览器、网络、性能、工程化等各方面八股文要点。例如其中的**《前端铜九铁十面试必备八股文——浏览器》<strong>深入总结了XSS/CSRF、防抖节流、事件机制等,</strong>《网络相关》**篇则整理了HTTP各版本特点等。这些系列文章语言精炼、要点突出,非常适合考前速览复习。</p></li><li><p><strong>CSDN博客:「2024年Web前端最新面试八股文」</strong> – <em>综合性前端面试知识大全</em>。该博文按章节详细列出了前端各领域典型题目和参考答案,从CSS、JS基础到框架、性能、安全一应俱全。内容更新至2024年末,涵盖面广且附有解释,适合作为知识盲点查漏和答案表述学习的参考。</p></li><li><p><strong>知乎专栏:</strong>《<strong>2024年面试必问的Web前端面试八股文及答案整理</strong>》 – 综合整理了一份前端核心考点宝典,涵盖<strong>JavaScript、CSS、ES6、Vue2/3、React、Node.js、小程序、HTTP、TypeScript</strong>等几乎所有类别。每个知识点都有详解答案,可用于在理解基础上背诵关键表述。这类知乎回答集合凝练了大量面经精华,质量较高。</p></li><li><p><strong>MDN Web Docs</strong>(Mozilla开发者文档) – <em>权威技术细节参考</em>。当遇到概念模糊时,MDN上的相关页面通常提供权威而清晰的解释。例如查看“事件循环(Event Loop)”条目可了解JS运行时模型的准确描述。MDN文档多为英文,但内容可信且细节充分,查阅具体概念(如HTTP缓存、CSS属性等)时非常有价值。</p></li><li><p><strong>牛客网 NowCoder 前端面试版块</strong> – 聚集了大量实时更新的面试经验帖和真题讨论。可以搜索“快手 前端 面经”获取往届真实问答情境,了解快手面试官爱问的问题类型。利用碎片时间翻阅几篇高赞面经,有助于掌握面试侧重点和应答技巧。不过需注意面经内容良莠不齐,切忌被他人负面经历影响心态。</p></li></ul>]]></content>
<summary type="html"><h2 id="1-Classification-of-important-knowledge-points-and-key-points-list"><a href="#1-Classification-of-important-knowledge-points-and-key</summary>
<category term="Frontend" scheme="https://longsizhuo.github.io/categories/Frontend/"/>
<category term="React" scheme="https://longsizhuo.github.io/tags/React/"/>
<category term="Frontend Framework" scheme="https://longsizhuo.github.io/tags/Frontend-Framework/"/>
<category term="Next.js" scheme="https://longsizhuo.github.io/tags/Next-js/"/>
<category term="SSR" scheme="https://longsizhuo.github.io/tags/SSR/"/>
<category term="SSG" scheme="https://longsizhuo.github.io/tags/SSG/"/>
</entry>
<entry>
<title>42</title>
<link href="https://longsizhuo.github.io/post/60fe0230.html"/>
<id>https://longsizhuo.github.io/post/60fe0230.html</id>
<published>2025-03-27T08:56:00.000Z</published>
<updated>2025-03-31T03:42:04.886Z</updated>
<content type="html"><![CDATA[<h1 id="QUESTION:"><a href="#QUESTION:" class="headerlink" title="QUESTION:"></a>QUESTION:</h1><p><a href="">42.md</a></p><h1 id="My-Think:"><a href="#My-Think:" class="headerlink" title="My Think:"></a>My Think:</h1><p>滚瓜烂熟的一道题, 全部靠背诵. 但是昨天又理解了一下, 画了一个GIF图供我自己理解, 代码如下,</p><p>图片举例: <code>[0,1,0,2,1,0,1,3,2,1,2,1]</code><br>该题的核心思想其实就是木桶原理, 我们将最外面的两个柱子视作玛丽亚之墙, 这个时候我们忽略玛丽亚之墙内部的城墙, 那么最多是不是可以装<code>min(leftmax, rightmax)</code>这么高的水呢?<br>也就是最短的柱子的水决定了它的”高度”. 但是我们想知道最多能装多少水, 还需要一个宽度. 于是这个时候我们就一根一根柱子看, 也就是说我们计算每”1”个宽度能装多少水, 然后加起来即可.<br>我们的左指针为<code>left</code>, 右指针为<code>right</code>, 我们再维护一个左边最高和右边最高.<br>当我们到达最外面的玛丽亚之墙的时候, 左最高即为<code>leftmax</code>, 右最高即为<code>rightmax</code>, 这个时候我们是无法判断可以装多少水的.<br>一直到<code>leftmost</code>!=<code>rightmost</code>的时候, 我们就可以判断了.<br><img src="/img_6.png" alt="img_6.png"><br>比如这一帧, 我们最多能装的是<code>leftmax</code>的水量, 即<code>2</code>, 但是因为我们这个时候左指针所在的柱子有一定高度<code>1</code>, 所以是<code>2-1=1</code>, 也就是我们能装<code>1</code>的水.<br>如果我们比较的不是<code>leftmost</code>和<code>rightmost</code>, 而是<code>leftmax</code>和<code>rightmax</code>, 我们就无法确定说这一个柱子为什么能够兜得住水, 它之所以能兜住水,必然是<=<code>leftmax</code>的</p><p>This is a problem I’ve memorized inside out — totally muscle memory. But I revisited it yesterday and tried to actually understand it. I even made a GIF to help myself visualize what’s happening. Here’s the code:</p><p>Let’s use the example: [0,1,0,2,1,0,1,3,2,1,2,1]</p><p>The core idea of this problem is basically the “bucket theory”:<br>We treat the two outermost bars as the “Walls of Maria” — and ignore the inner ones for now.<br>If that’s the case, then the max height of water we can hold is min(leftmax, rightmax).<br>In other words, the shorter wall decides the water level.</p><p>But height alone isn’t enough — we also need width to compute the actual amount of water.<br>So we look at each bar one by one, and calculate how much water we can trap on top of it, then sum it all up.</p><p>We use two pointers: left and right, and also keep track of the highest wall on the left (leftmax) and the highest wall on the right (rightmax).</p><p>When our pointer reaches the end of the string (or the two walls meet), that means we’ve gone through all the characters — that’s when we know we have a valid answer.</p><p>Take this specific frame as an example:<br><img src="/img_6.png" alt="img_6.png"></p><p>At this point, the max water we can hold is leftmax = 2, but the current column has height 1, so we can trap: </p><p><code>2 - 1 = 1</code> unit of water.</p><p>If we were comparing leftmax and rightmax directly, we wouldn’t know why this particular column can hold water. The only reason it can trap water is because its height is less than or equal to leftmax.</p><h1 id="Code:"><a href="#Code:" class="headerlink" title="Code:"></a>Code:</h1><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Solution</span>:</span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">trap</span>(<span class="params">self, height: <span class="built_in">list</span>[<span class="built_in">int</span>]</span>) -> <span class="built_in">int</span>:</span><br><span class="line"> ans = leftmost = rightmost = <span class="number">0</span></span><br><span class="line"> left, right = <span class="number">0</span>, <span class="built_in">len</span>(height) - <span class="number">1</span></span><br><span class="line"> <span class="keyword">while</span> left < right:</span><br><span class="line"> leftmost = <span class="built_in">max</span>(leftmost, height[left])</span><br><span class="line"> rightmost = <span class="built_in">max</span>(rightmost, height[right])</span><br><span class="line"> <span class="keyword">if</span> leftmost <= rightmost:</span><br><span class="line"> ans += leftmost - height[left]</span><br><span class="line"> left += <span class="number">1</span></span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> ans += rightmost - height[right]</span><br><span class="line"> right -= <span class="number">1</span></span><br><span class="line"> <span class="keyword">return</span> ans</span><br></pre></td></tr></table></figure><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> matplotlib.pyplot <span class="keyword">as</span> plt</span><br><span class="line"><span class="keyword">import</span> matplotlib.animation <span class="keyword">as</span> animation</span><br><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"></span><br><span class="line"><span class="comment"># Given height list for illustration</span></span><br><span class="line">height = [<span class="number">0</span>,<span class="number">1</span>,<span class="number">0</span>,<span class="number">2</span>,<span class="number">1</span>,<span class="number">0</span>,<span class="number">1</span>,<span class="number">3</span>,<span class="number">2</span>,<span class="number">1</span>,<span class="number">2</span>,<span class="number">1</span>]</span><br><span class="line"></span><br><span class="line"><span class="comment"># Initialize variables as in the function</span></span><br><span class="line">left, right = <span class="number">0</span>, <span class="built_in">len</span>(height) - <span class="number">1</span></span><br><span class="line">leftmax = rightmax = <span class="number">0</span></span><br><span class="line">ans = <span class="number">0</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># For animation, store each frame's water level and pointers</span></span><br><span class="line">frames = []</span><br><span class="line"></span><br><span class="line"><span class="comment"># Simulate the logic and capture frames</span></span><br><span class="line"><span class="keyword">while</span> left < right:</span><br><span class="line"> leftmax = <span class="built_in">max</span>(leftmax, height[left])</span><br><span class="line"> rightmax = <span class="built_in">max</span>(rightmax, height[right])</span><br><span class="line"> water = [<span class="number">0</span>] * <span class="built_in">len</span>(height)</span><br><span class="line"> <span class="keyword">if</span> leftmax <= rightmax:</span><br><span class="line"> trapped = <span class="built_in">max</span>(<span class="number">0</span>, leftmax - height[left])</span><br><span class="line"> ans += trapped</span><br><span class="line"> water[left] = trapped</span><br><span class="line"> frames.append((height.copy(), water.copy(), left, right))</span><br><span class="line"> left += <span class="number">1</span></span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> trapped = <span class="built_in">max</span>(<span class="number">0</span>, rightmax - height[right])</span><br><span class="line"> ans += trapped</span><br><span class="line"> water[right] = trapped</span><br><span class="line"> frames.append((height.copy(), water.copy(), left, right))</span><br><span class="line"> right -= <span class="number">1</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Create animation</span></span><br><span class="line">fig, ax = plt.subplots(figsize=(<span class="number">10</span>, <span class="number">5</span>))</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">update</span>(<span class="params">frame</span>):</span><br><span class="line"> ax.clear()</span><br><span class="line"> heights, water, l_ptr, r_ptr = frame</span><br><span class="line"> indices = np.arange(<span class="built_in">len</span>(heights))</span><br><span class="line"> ax.bar(indices, heights, color=<span class="string">'grey'</span>, edgecolor=<span class="string">'black'</span>)</span><br><span class="line"> ax.bar(indices, water, bottom=heights, color=<span class="string">'blue'</span>, edgecolor=<span class="string">'blue'</span>, alpha=<span class="number">0.6</span>)</span><br><span class="line"> ax.axvline(l_ptr, color=<span class="string">'green'</span>, linestyle=<span class="string">'--'</span>, label=<span class="string">'Left Pointer'</span>)</span><br><span class="line"> ax.axvline(r_ptr, color=<span class="string">'red'</span>, linestyle=<span class="string">'--'</span>, label=<span class="string">'Right Pointer'</span>)</span><br><span class="line"> ax.set_ylim(<span class="number">0</span>, <span class="built_in">max</span>(height) + <span class="number">3</span>)</span><br><span class="line"> ax.set_title(<span class="string">"Trapping Rain Water Animation"</span>)</span><br><span class="line"> ax.legend()</span><br><span class="line"></span><br><span class="line">ani = animation.FuncAnimation(fig, update, frames=frames, interval=<span class="number">500</span>, repeat=<span class="literal">False</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">from</span> IPython.display <span class="keyword">import</span> HTML</span><br><span class="line">ani.save(<span class="string">"trapping_rain_water.gif"</span>, writer=<span class="string">"pillow"</span>, fps=<span class="number">2</span>) <span class="comment"># 保存为 GIF</span></span><br></pre></td></tr></table></figure>]]></content>
<summary type="html"><h1 id="QUESTION:"><a href="#QUESTION:" class="headerlink" title="QUESTION:"></a>QUESTION:</h1><p><a href="">42.md</a></p>
<h1 id="My-Think:</summary>
<category term="Python" scheme="https://longsizhuo.github.io/tags/Python/"/>
<category term="Answer" scheme="https://longsizhuo.github.io/tags/Answer/"/>
</entry>
<entry>
<title>93. Restore IP Addresses</title>
<link href="https://longsizhuo.github.io/post/9d0d3b9c.html"/>
<id>https://longsizhuo.github.io/post/9d0d3b9c.html</id>
<published>2025-03-25T03:03:00.000Z</published>
<updated>2025-03-31T03:42:04.886Z</updated>
<content type="html"><![CDATA[<h1 id="QUESTION:"><a href="#QUESTION:" class="headerlink" title="QUESTION:"></a>QUESTION:</h1><p><a href="https://leetcode.cn/problems/restore-ip-addresses/description/?envType=company&envId=mihoyo&favoriteSlug=mihoyo-all">93. Restore IP Addresses</a></p><h1 id="My-Think:"><a href="#My-Think:" class="headerlink" title="My Think:"></a>My Think:</h1><p>This MiHoYo coding test question is very similar to LeetCode 46 (Permutations), and both rely on the backtracking approach.</p><p>As shown in the code, during the first traversal, we may get something like <code>['2', '5', '5', '2']</code> as our initial parts, but at this point, we haven’t traversed the entire string yet.</p><p>When we enter the next level of DFS, the pointer moves forward by +length, so it effectively moves to the far right of the current segment.<br>If the pointer has reached the end of the string, it means we’ve visited all characters — in this case, we’ve found one valid answer and can add it to the result list.</p><p>One important note: <code>parts + [part]</code> is pass-by-value, not by reference like in LeetCode 46.<br>This means we don’t need to manually undo changes (i.e., no need to backtrack with pop()), because each recursive call creates a new list.</p><p>现在在做的是MiHoyo的笔试题, 这个和46.permutation非常相似, 都是回溯思想.</p><p>如代码所示, 在第一遍遍历中, 我们会得到<code>['2','5','5','2']</code> 作为第一个parts, 但是我们并没有遍历完整个字符串.</p><p>这个时候如果我们进入新的dfs的时候, 我们的指针因为刚刚<code>+length</code>, 所以我们实际上<br>指到的是最右边,所以当当前指针已经指到最右边的时候, 说明我们遍历完了所有字符, 那么这就是答案之一.</p><p><code>parts + [part]</code> 是值传递而不是46的引用传递, 所以不用手动撤销更改</p><h1 id="Code:"><a href="#Code:" class="headerlink" title="Code:"></a>Code:</h1><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> typing <span class="keyword">import</span> <span class="type">List</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Solution</span>:</span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">restoreIpAddresses</span>(<span class="params">self, s: <span class="built_in">str</span></span>) -> <span class="type">List</span>[<span class="built_in">str</span>]:</span><br><span class="line"> res = []</span><br><span class="line"></span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">backtrack</span>(<span class="params">start: <span class="built_in">int</span>, parts: <span class="type">List</span>[<span class="built_in">str</span>]</span>):</span><br><span class="line"> <span class="comment"># 终止条件:正好4段且用完所有字符</span></span><br><span class="line"> <span class="comment"># Stop condition: exactly 4 segments and all characters used up</span></span><br><span class="line"> <span class="keyword">if</span> <span class="built_in">len</span>(parts) == <span class="number">4</span>:</span><br><span class="line"> <span class="keyword">if</span> start == <span class="built_in">len</span>(s):</span><br><span class="line"> res.append(<span class="string">"."</span>.join(parts))</span><br><span class="line"> <span class="keyword">return</span></span><br><span class="line"></span><br><span class="line"> <span class="keyword">for</span> length <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">1</span>, <span class="number">4</span>): <span class="comment"># 每段长度1~3 Each segment length 1~3</span></span><br><span class="line"> <span class="keyword">if</span> start + length > <span class="built_in">len</span>(s):</span><br><span class="line"> <span class="keyword">break</span></span><br><span class="line"> part = s[start:start+length]</span><br><span class="line"></span><br><span class="line"> <span class="comment"># 前导0非法,但0本身合法</span></span><br><span class="line"> <span class="comment"># Leading 0 is illegal, but 0 itself is legal</span></span><br><span class="line"> <span class="keyword">if</span> <span class="built_in">len</span>(part) > <span class="number">1</span> <span class="keyword">and</span> part[<span class="number">0</span>] == <span class="string">'0'</span>:</span><br><span class="line"> <span class="keyword">continue</span></span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> <span class="built_in">int</span>(part) <= <span class="number">255</span>:</span><br><span class="line"> backtrack(start + length, parts + [part]) <span class="comment"># 注意用 + 避免污染 We need to use + to avoid pollution</span></span><br><span class="line"></span><br><span class="line"> backtrack(<span class="number">0</span>, [])</span><br><span class="line"> <span class="keyword">return</span> res</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html"><h1 id="QUESTION:"><a href="#QUESTION:" class="headerlink" title="QUESTION:"></a>QUESTION:</h1><p><a href="https://leetcode.cn/problems/rest</summary>
<category term="Python" scheme="https://longsizhuo.github.io/tags/Python/"/>
<category term="Answer" scheme="https://longsizhuo.github.io/tags/Answer/"/>
</entry>
<entry>
<title>46.permutations</title>
<link href="https://longsizhuo.github.io/post/d567a4cd.html"/>
<id>https://longsizhuo.github.io/post/d567a4cd.html</id>
<published>2025-03-24T06:07:09.408Z</published>
<updated>2025-03-25T08:25:30.582Z</updated>
<content type="html"><![CDATA[<h1 id="Description"><a href="#Description" class="headerlink" title="Description:"></a>Description:</h1><p>Given an array nums of distinct integers, return all the possible permutations. You can return the answer in any order.</p><p>Example 1:</p><p>Input: nums = [1,2,3]<br>Output: [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]<br>Example 2:</p><p>Input: nums = [0,1]<br>Output: [[0,1],[1,0]]<br>Example 3:</p><p>Input: nums = [1]<br>Output: [[1]]</p><h1 id="Thinking"><a href="#Thinking" class="headerlink" title="Thinking:"></a>Thinking:</h1><p>This question is more like a tree problem.<br>like the tree below:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line">dfs(0): nums = [1,2,3]</span><br><span class="line">|</span><br><span class="line">|-- i=0: swap(0,0) -> [1,2,3]</span><br><span class="line">| |</span><br><span class="line">| |-- dfs(1)</span><br><span class="line">| |-- i=1: swap(1,1) -> [1,2,3]</span><br><span class="line">| | |-- dfs(2): append [1,2,3]</span><br><span class="line">| |-- i=2: swap(1,2) -> [1,3,2]</span><br><span class="line">| |-- dfs(2): append [1,3,2]</span><br><span class="line">|</span><br><span class="line">|-- i=1: swap(0,1) -> [2,1,3]</span><br><span class="line">| |</span><br><span class="line">| |-- dfs(1)</span><br><span class="line">| |-- i=1: swap(1,1) -> [2,1,3]</span><br><span class="line">| | |-- dfs(2): append [2,1,3]</span><br><span class="line">| |-- i=2: swap(1,2) -> [2,3,1]</span><br><span class="line">| |-- dfs(2): append [2,3,1]</span><br><span class="line">|</span><br><span class="line">|-- i=2: swap(0,2) -> [3,2,1]</span><br><span class="line"> |</span><br><span class="line"> |-- dfs(1)</span><br><span class="line"> |-- i=1: swap(1,1) -> [3,2,1]</span><br><span class="line"> | |-- dfs(2): append [3,2,1]</span><br><span class="line"> |-- i=2: swap(1,2) -> [3,1,2]</span><br><span class="line"> |-- dfs(2): append [3,1,2]</span><br><span class="line"></span><br></pre></td></tr></table></figure><p>We swap the current position index with each possible candidate <code>i</code> from <code>index</code> to the end. They can be seen as left and right pointers: <code>index</code> determines which position we’re filling, and <code>i</code> tries different numbers to place there.</p><p>Before the recursive call, we swap <code>nums[i]</code> and <code>nums[index]</code> to try placing a new number at position index. If we reach the last position (<code>index == len(nums) - 1</code>), we add the current permutation to the answer list.<br>After recursion, we swap back to restore the original state (backtracking).</p><h1 id="Code"><a href="#Code" class="headerlink" title="Code:"></a>Code:</h1><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Solution</span>:</span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">permute</span>(<span class="params">self, nums: <span class="type">List</span>[<span class="built_in">int</span>]</span>) -> <span class="type">List</span>[<span class="type">List</span>[<span class="built_in">int</span>]]:</span><br><span class="line"> <span class="comment"># index</span></span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">dfs</span>(<span class="params">index</span>):</span><br><span class="line"> <span class="comment"># Reach the last element</span></span><br><span class="line"> <span class="keyword">if</span> index == <span class="built_in">len</span>(nums) - <span class="number">1</span>:</span><br><span class="line"> res.append(<span class="built_in">list</span>(nums))</span><br><span class="line"> <span class="keyword">return</span></span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(index, <span class="built_in">len</span>(nums)):</span><br><span class="line"> nums[i], nums[index] = nums[index], nums[i]</span><br><span class="line"> dfs(index + <span class="number">1</span>)</span><br><span class="line"> nums[i], nums[index] = nums[index], nums[i]</span><br><span class="line"></span><br><span class="line"> res = []</span><br><span class="line"> dfs(<span class="number">0</span>)</span><br><span class="line"> <span class="keyword">return</span> res</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html"><h1 id="Description"><a href="#Description" class="headerlink" title="Description:"></a>Description:</h1><p>Given an array nums of distinct </summary>
<category term="Python" scheme="https://longsizhuo.github.io/tags/Python/"/>
<category term="9021" scheme="https://longsizhuo.github.io/tags/9021/"/>
<category term="tree" scheme="https://longsizhuo.github.io/tags/tree/"/>
</entry>
<entry>
<title>9021_TUT_3_25T1</title>
<link href="https://longsizhuo.github.io/post/974decd3.html"/>
<id>https://longsizhuo.github.io/post/974decd3.html</id>
<published>2025-03-06T13:00:00.000Z</published>
<updated>2025-03-21T08:12:49.416Z</updated>
<content type="html"><![CDATA[<h1 id="Exercise-1"><a href="#Exercise-1" class="headerlink" title="Exercise 1"></a>Exercise 1</h1><h3 id="Problem-Description"><a href="#Problem-Description" class="headerlink" title="Problem Description:"></a>Problem Description:</h3><p>You are given two integers, <code>m</code> and <code>n</code>, where:</p><ul><li><code>m</code> represents the number of repeated units (patterns).</li><li><code>n</code> represents the number of elements (underscores) within each unit.</li></ul><p>The goal is to generate a string where:</p><ul><li>Each unit contains <code>n</code> underscores (_), separated by <code>|</code>.</li><li>These units are then concatenated together, separated by <code>*</code>.</li></ul><h3 id="My-Solution"><a href="#My-Solution" class="headerlink" title="My Solution:"></a>My Solution:</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">generate_struct</span>(<span class="params">n</span>):</span><br><span class="line"> <span class="keyword">return</span> <span class="string">'|'</span>.join(n * [<span class="string">'_'</span>])</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">f1</span>(<span class="params">m, n</span>):</span><br><span class="line"> <span class="keyword">return</span> <span class="string">' * '</span>.join(m * [generate_struct(n)])</span><br></pre></td></tr></table></figure><h4 id="My-Thought-Process"><a href="#My-Thought-Process" class="headerlink" title="My Thought Process:"></a>My Thought Process:</h4><p>I think of each unit as a separate structure. So, I decompose the problem by breaking down the smallest unit, which is the structure made of underscores joined by <code>|</code>.<br>After constructing each unit, I use <code>join()</code> to combine them together using <code>*</code>.</p><h4 id="Helper-Function-generate-struct-n"><a href="#Helper-Function-generate-struct-n" class="headerlink" title="Helper Function generate_struct(n):"></a>Helper Function generate_struct(n):</h4><p>This function generates the basic structure.<br>It creates a list of underscores (<code>_</code>) of length n and joins them with <code>|</code>.<br>Example: If <code>n = 2</code>, the result will be “<code>_|_</code>“.</p><h3 id="Standard-Solution"><a href="#Standard-Solution" class="headerlink" title="Standard Solution:"></a>Standard Solution:</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f1</span>(<span class="params">m, n</span>):</span><br><span class="line"> <span class="keyword">return</span> <span class="string">' * '</span>.join(<span class="string">'|'</span>.join(<span class="string">'_'</span> <span class="keyword">for</span> _ <span class="keyword">in</span> <span class="built_in">range</span>(n)) <span class="keyword">for</span> _ <span class="keyword">in</span> <span class="built_in">range</span>(m))</span><br></pre></td></tr></table></figure><h3 id="Concise-Expression"><a href="#Concise-Expression" class="headerlink" title="Concise Expression:"></a>Concise Expression:</h3><p>The inner <code>join</code> creates a string of <code>n</code> underscores joined by <code>|</code> using a generator expression <code>('_' for _ in range(n))</code>.<br>The outer <code>join</code> repeats this process <code>m</code> times and concatenates the units using <code>*</code>.</p><p>In summary, my solution focuses on modularity by breaking down the problem into smaller parts (like creating a structural unit), whereas the standard solution compresses everything into one line using list comprehensions.</p><h1 id="Exercise-2"><a href="#Exercise-2" class="headerlink" title="Exercise 2"></a>Exercise 2</h1><h3 id="Problem-Description-1"><a href="#Problem-Description-1" class="headerlink" title="Problem Description:"></a>Problem Description:</h3><p>The goal is to generate a pattern based on the digits of a given number n. Specifically:</p><p>If a digit is odd, it should be represented by a black square (⬛).<br>If a digit is even, it should be represented by a white square (⬜).<br>The program takes a number n as input and prints a string of squares corresponding to the digits of n.</p><h3 id="My-Solution-1"><a href="#My-Solution-1" class="headerlink" title="My Solution:"></a>My Solution:</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f2</span>(<span class="params">n</span>):</span><br><span class="line"> ans = <span class="string">''</span></span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">str</span>(n):</span><br><span class="line"> <span class="keyword">if</span> <span class="built_in">int</span>(i) % <span class="number">2</span> == <span class="number">0</span>:</span><br><span class="line"> ans += <span class="string">'⬜'</span></span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> ans += <span class="string">'⬛'</span></span><br><span class="line"> <span class="built_in">print</span>(ans)</span><br></pre></td></tr></table></figure><h4 id="My-Thought-Process-1"><a href="#My-Thought-Process-1" class="headerlink" title="My Thought Process:"></a>My Thought Process:</h4><ol><li><p>Loop through each digit:<br>Convert the number n to a string to iterate over each digit individually.</p></li><li><p>Check if the digit is even or odd:<br>Convert each digit back to an integer and use the modulus operator (% 2) to check if the digit is even or odd.</p></li><li><p>Append the corresponding square:</p><ul><li>If the digit is even, append a white square (⬜) to the result string.</li><li>If the digit is odd, append a black square (⬛).</li></ul></li><li><p>Print the final string:<br>After processing all the digits, print the final string containing black and white squares.</p></li></ol><h3 id="Standard-Solution-1"><a href="#Standard-Solution-1" class="headerlink" title="Standard Solution:"></a>Standard Solution:</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f2</span>(<span class="params">n</span>):</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">''</span>.join({<span class="number">0</span>: <span class="string">'\u2b1c'</span>, <span class="number">1</span>: <span class="string">'\u2b1b'</span>}[<span class="built_in">int</span>(d) % <span class="number">2</span>] <span class="keyword">for</span> d <span class="keyword">in</span> <span class="built_in">str</span>(n)))</span><br></pre></td></tr></table></figure><p>Dr.Martin’s solution is:</p><ol><li>More compact and Pythonic.</li><li>Uses a dictionary and list comprehension for brevity and efficiency.</li><li>The Unicode characters for the squares are referenced directly using their escape sequences (<code>\u2b1c</code> for white, <code>\u2b1b</code> for black).</li></ol><h1 id="Exercise-3"><a href="#Exercise-3" class="headerlink" title="Exercise 3"></a>Exercise 3</h1><h3 id="Problem-Description-2"><a href="#Problem-Description-2" class="headerlink" title="Problem Description:"></a>Problem Description:</h3><p>In this task, the number <code>n</code> is treated as a number expressed in different bases (ranging from 2 to 10), and we aim to convert it into its corresponding base 10 value for each of these bases, where the conversion is valid.</p><p>For n = 2143:</p><ul><li><code>2143</code> in base <code>5</code> is equivalent to <code>298</code> in base <code>10</code>.</li><li><code>2143</code> in base <code>6</code> is equivalent to <code>495</code> in base <code>10</code>.</li><li>And so on.</li></ul><p>The goal is to iterate over different base systems from 2 to 10, treat the input number <code>n</code> as if it is expressed in each base, and then convert it to base 10.</p><h3 id="My-Solution-2"><a href="#My-Solution-2" class="headerlink" title="My Solution:"></a>My Solution:</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f3</span>(<span class="params">n: <span class="built_in">int</span></span>):</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">2</span>, <span class="number">11</span>):</span><br><span class="line"> <span class="keyword">try</span>:</span><br><span class="line"> <span class="comment"># Treat n as a number in base i and convert it to base 10</span></span><br><span class="line"> value = <span class="built_in">int</span>(<span class="built_in">str</span>(n), i)</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">f'<span class="subst">{n}</span> is <span class="subst">{value}</span> in base <span class="subst">{i}</span>'</span>)</span><br><span class="line"> <span class="keyword">except</span> ValueError:</span><br><span class="line"> <span class="keyword">pass</span></span><br></pre></td></tr></table></figure><h4 id="My-Thought-Process-2"><a href="#My-Thought-Process-2" class="headerlink" title="My Thought Process:"></a>My Thought Process:</h4><ol><li><p>Iterating over Bases (2 to 10):</p><ul><li>We loop through the base values i ranging from 2 to 10.</li></ul></li><li><p>Conversion Using <code>int()</code>:</p><ul><li>For each base <code>i</code>, we treat the number <code>n</code> as a number in that base. To do this, we first convert <code>n</code> to a string (<code>str(n)</code>) and then use <code>int()</code> to interpret it as a base <code>i</code> number.</li><li>If the digits of <code>n</code> are valid for base <code>i</code>, this conversion succeeds, and the result is the base 10 equivalent of <code>n</code>.</li><li>If the digits of n are not valid for base i (for example, if base 2 is used and n contains digits greater than 1), a ValueError is raised, and we skip the invalid base.</li></ul></li><li><p>Handling Errors with <code>try-except</code>:</p><ul><li>The <code>try-except</code> block ensures that invalid bases are skipped, allowing us to handle cases where the digits in <code>n</code> are not valid for a particular base.</li></ul></li></ol><h3 id="Standard-Solution-2"><a href="#Standard-Solution-2" class="headerlink" title="Standard Solution:"></a>Standard Solution:</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f3</span>(<span class="params">n</span>):</span><br><span class="line"> n_as_string = <span class="built_in">str</span>(n)</span><br><span class="line"> min_base = <span class="built_in">max</span>(<span class="number">2</span>, <span class="built_in">max</span>({<span class="built_in">int</span>(d) <span class="keyword">for</span> d <span class="keyword">in</span> n_as_string}) + <span class="number">1</span>)</span><br><span class="line"> <span class="keyword">for</span> b <span class="keyword">in</span> <span class="built_in">range</span>(min_base, <span class="number">11</span>):</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">f'<span class="subst">{n}</span> is <span class="subst">{<span class="built_in">int</span>(n_as_string, b)}</span> in base <span class="subst">{b}</span>'</span>)</span><br></pre></td></tr></table></figure><p>It skips the bases where the digits in n are not valid, and it uses a set comprehension to extract the unique digits from n_as_string. The maximum digit is then used to determine the minimum base to start iterating from.</p><h1 id="Exercise-4"><a href="#Exercise-4" class="headerlink" title="Exercise 4"></a>Exercise 4</h1><h3 id="Problem-Description-3"><a href="#Problem-Description-3" class="headerlink" title="Problem Description:"></a>Problem Description:</h3><p>The task is to create a function <code>f4(n, base)</code> that returns a dictionary D, where:</p><p>Keys are integers from <code>0</code> to <code>n</code>.<br>Values are tuples that represent the base <code>base</code> representation of each key, converted from base 10.</p><h3 id="My-Solution-3"><a href="#My-Solution-3" class="headerlink" title="My Solution:"></a>My Solution:</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">convert_to_base</span>(<span class="params">n, base</span>):</span><br><span class="line"> <span class="keyword">if</span> n == <span class="number">0</span>:</span><br><span class="line"> <span class="keyword">return</span> <span class="string">'0'</span></span><br><span class="line"> digits = []</span><br><span class="line"> <span class="keyword">while</span> n:</span><br><span class="line"> digits.append(<span class="built_in">str</span>(n % base))</span><br><span class="line"> n //= base</span><br><span class="line"> <span class="keyword">return</span> <span class="string">''</span>.join(digits[::-<span class="number">1</span>])</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">f4</span>(<span class="params">n: <span class="built_in">int</span>, base: <span class="built_in">int</span></span>):</span><br><span class="line"> D = {}</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, n + <span class="number">1</span>):</span><br><span class="line"> D[i] = <span class="built_in">tuple</span>(<span class="built_in">map</span>(<span class="built_in">int</span>, convert_to_base(i, base)))</span><br><span class="line"> <span class="keyword">return</span> D</span><br></pre></td></tr></table></figure><h4 id="My-Thought-Process-3"><a href="#My-Thought-Process-3" class="headerlink" title="My Thought Process:"></a>My Thought Process:</h4><ol><li><p>Helper Function <code>convert_to_base(n, base)</code>:</p><ul><li>This function converts a number <code>n</code> from base 10 to the specified base.</li><li>We use a while loop to repeatedly take the modulus (<code>n % base</code>) and append the remainder to the list <code>digits</code>.</li><li>We then divide <code>n</code> by <code>base</code> <code>(n //= base)</code> to reduce it for the next iteration.</li><li>After collecting all digits, we reverse the list and return it as a string.</li></ul></li><li><p>Main Function <code>f4(n, base)</code>:<br>We initialize an empty dictionary <code>D</code>.<br>For each number <code>i</code> from <code>0</code> to <code>n</code>, we convert <code>i</code> to the given base using <code>convert_to_base()</code>.<br>The converted base digits are then mapped to integers and stored in a tuple as the value for each key <code>i</code> in the dictionary.</p></li></ol><h3 id="Explanation-of-Why-map-is-not-Pythonic"><a href="#Explanation-of-Why-map-is-not-Pythonic" class="headerlink" title="Explanation of Why map() is not Pythonic:"></a>Explanation of Why <code>map()</code> is not Pythonic:</h3><p>In the function f4, the use of <code>map(int, convert_to_base(i, base))</code> applies the <code>int</code> function<br>to each element of the result from <code>convert_to_base</code>, effectively converting each character to an integer.</p><p>However, it’s worth noting that the <code>map()</code> function, which originates from functional programming,<br>has largely been superseded by more Pythonic constructs such as list comprehensions.</p><p>These comprehensions are generally considered superior for several reasons:</p><ul><li>They are more elegant and concise.</li><li>They tend to be shorter in terms of syntax, making the code easier to read.</li><li>They are easier to understand for most people, especially those who are more familiar with Python’s<br>standard syntax rather than functional programming constructs.</li><li>In many cases, they are also more efficient in terms of performance.</li></ul><p>For example, instead of using <code>map(int, ...)</code>, the same functionality could be achieved with a<br>list comprehension, like so:</p><p>D[i] = tuple([int(digit) for digit in convert_to_base(i, base)])</p><p>This list comprehension achieves the same result but follows a more modern Pythonic style.</p><h3 id="Standard-Solution-3"><a href="#Standard-Solution-3" class="headerlink" title="Standard Solution:"></a>Standard Solution:</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f4</span>(<span class="params">n, base</span>):</span><br><span class="line"> D = {<span class="number">0</span>: (<span class="number">0</span>,)}</span><br><span class="line"> <span class="keyword">for</span> m <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">1</span>, n + <span class="number">1</span>):</span><br><span class="line"> digits = []</span><br><span class="line"> p = m</span><br><span class="line"> <span class="keyword">while</span> p:</span><br><span class="line"> digits.append(p % base)</span><br><span class="line"> p //= base</span><br><span class="line"> D[m] = <span class="built_in">tuple</span>(<span class="built_in">reversed</span>(digits))</span><br><span class="line"> <span class="keyword">return</span> D</span><br></pre></td></tr></table></figure><p>Both solutions are valid and achieve the same result. My approach uses a helper function for base conversion, which adds modularity,<br>whereas the standard solution is more concise and directly integrates the conversion logic into the main function.</p><h1 id="Exercise-5"><a href="#Exercise-5" class="headerlink" title="Exercise 5"></a>Exercise 5</h1><p>At the first, try to run this:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">print</span>(<span class="number">0.1</span> + <span class="number">0.2</span>)</span><br></pre></td></tr></table></figure><p>What happened? The result is not 0.3, but 0.30000000000000004. Why?</p><h3 id="Problem-Description-4"><a href="#Problem-Description-4" class="headerlink" title="Problem Description:"></a>Problem Description:</h3><p>The approach we are using in this exercise is designed to expose the limitations of floating-point arithmetic in computers. Let’s break down why this approach leads to precision inaccuracies and why other methods might not reveal these issues as clearly.</p><p>This problem can seem complex, and it’s designed to highlight the subtleties of floating-point arithmetic. Let’s walk through the logic using the test cases to figure out what the function does.</p><h3 id="Key-Concepts"><a href="#Key-Concepts" class="headerlink" title="Key Concepts:"></a>Key Concepts:</h3><ul><li><strong>Floating-point numbers</strong>: Computers store floating-point numbers using a binary format, which often introduces precision errors.</li><li><strong>Precision</strong>: We’re working with two types of precision in this function—simple precision (same as the length of the fractional part) and double precision (twice that length).</li></ul><h3 id="Solution"><a href="#Solution" class="headerlink" title="Solution:"></a>Solution:</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f5</span>(<span class="params">integral_part, fractional_part</span>):</span><br><span class="line"> <span class="comment"># Calculate the number of digits in the fractional part</span></span><br><span class="line"> precision = <span class="built_in">len</span>(<span class="built_in">str</span>(fractional_part))</span><br><span class="line"> </span><br><span class="line"> <span class="comment"># Concatenate the integral and fractional parts as strings, then convert to a float</span></span><br><span class="line"> a_float = <span class="built_in">float</span>(<span class="built_in">str</span>(integral_part) + <span class="string">'.'</span> + <span class="built_in">str</span>(fractional_part))</span><br><span class="line"> </span><br><span class="line"> <span class="comment"># Format the float with precision equal to the number of digits in the fractional part (simple precision)</span></span><br><span class="line"> simple_precision = <span class="string">f'<span class="subst">{a_float:.{precision}</span>f}'</span></span><br><span class="line"> </span><br><span class="line"> <span class="comment"># Append a number of zeros equal to the fractional part length to the simple precision value (extended precision)</span></span><br><span class="line"> extended_simple_precision = simple_precision + <span class="string">'0'</span> * precision</span><br><span class="line"> </span><br><span class="line"> <span class="comment"># Format the float with precision equal to twice the number of fractional digits (double precision)</span></span><br><span class="line"> double_precision = <span class="string">f'<span class="subst">{a_float:.{precision * <span class="number">2</span>}</span>f}'</span></span><br><span class="line"> </span><br><span class="line"> <span class="comment"># Print the first part of the output</span></span><br><span class="line"> <span class="built_in">print</span>(<span class="string">'With'</span>, precision * <span class="number">2</span>, <span class="string">'digits after the decimal point, '</span>, end=<span class="string">''</span>)</span><br><span class="line"> </span><br><span class="line"> <span class="comment"># Compare if extended precision and double precision values are the same</span></span><br><span class="line"> <span class="keyword">if</span> extended_simple_precision == double_precision:</span><br><span class="line"> <span class="comment"># If they are the same, it means the float is precise and has trailing zeros</span></span><br><span class="line"> <span class="built_in">print</span>(simple_precision, <span class="string">'prints out with'</span>, precision, <span class="string">'trailing'</span>,</span><br><span class="line"> precision == <span class="number">1</span> <span class="keyword">and</span> <span class="string">'zero,'</span> <span class="keyword">or</span> <span class="string">'zeroes,'</span>, <span class="string">'namely, as'</span>,</span><br><span class="line"> extended_simple_precision</span><br><span class="line"> )</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> <span class="comment"># If not, there is a precision error, and no trailing zeros</span></span><br><span class="line"> <span class="built_in">print</span>(simple_precision, <span class="string">'prints out as'</span>, double_precision)</span><br></pre></td></tr></table></figure><p>Our function attempts to check and display this floating point error with simple precision (<code>simple_precision</code>) and double precision (<code>double_precision</code>). The error becomes more obvious when we represent floating point numbers with higher precision (double the number of decimal places). So in this way, we show that floating point numbers are not always actually stored as we expect them to be with more precise representation.</p><h1 id="Exercise-6"><a href="#Exercise-6" class="headerlink" title="Exercise 6"></a>Exercise 6</h1><h3 id="Problem-Description-5"><a href="#Problem-Description-5" class="headerlink" title="Problem Description:"></a>Problem Description:</h3><p>In this task, we are given:</p><ul><li>A list <code>L</code>, which contains multiple sub-lists of integers, and all sub-lists have the same length <code>n</code>.</li><li>A list <code>fields</code>, which is a permutation of <code>{1, ..., n}</code>.</li></ul><p>We are required to sort the list L by using a multi-key sorting mechanism, where:</p><ul><li>First, the elements in <code>L</code> are sorted based on the position given by the first element of <code>fields</code>.</li><li>If two sub-lists are equal based on the first field, we move to the second field, and so on.</li><li>Finally, if required, the sorting proceeds up to the last field in <code>fields</code>.</li></ul><h3 id="Example-of-Fields-Explanation"><a href="#Example-of-Fields-Explanation" class="headerlink" title="Example of Fields Explanation:"></a>Example of Fields Explanation:</h3><p>If <code>fields = [2, 1]</code>, it means:</p><ol><li>First, sort based on the second element of each sublist.</li><li>If there are ties (same values in the second position), sort based on the first element.</li></ol><h3 id="My-Solution-4"><a href="#My-Solution-4" class="headerlink" title="My Solution:"></a>My Solution:</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f6</span>(<span class="params">L, fields</span>):</span><br><span class="line"> <span class="keyword">return</span> <span class="built_in">sorted</span>(L, key=<span class="keyword">lambda</span> x: [x[i-<span class="number">1</span>] <span class="keyword">for</span> i <span class="keyword">in</span> fields])</span><br></pre></td></tr></table></figure><ol><li><p>Sorting with sorted():<br>The <code>sorted()</code> function is used to sort the list <code>L</code>.<br>The key parameter defines how the sorting will be performed.</p></li><li><p>Lambda Function:<br>The lambda function defines how the sublists will be sorted. It generates a list of values for each sublist based on the positions specified in <code>fields</code>.<br>For example, if <code>fields = [2, 1]</code>, the lambda function will extract the second and first elements from each sublist in that order, and sorting will be done based on this new list.</p></li><li><p>Key Structure:<br>The key is a list of elements from each sublist, indexed by the positions specified in fields. We use <code>x[i - 1]</code> because fields is <code>1-based</code>, and list indexing in Python is <code>0-based</code>.</p></li><li><p>What is Lambda Function?</p></li></ol><p>For example:</p><p>We have:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">f = <span class="keyword">lambda</span> x: x * x</span><br></pre></td></tr></table></figure><p>This is equivalent to:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f</span>(<span class="params">x</span>):</span><br><span class="line"> <span class="keyword">return</span> x * x</span><br></pre></td></tr></table></figure><p>And lambda function in a sorted function is used to define a custom sorting key.</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">L = [(<span class="number">1</span>,<span class="number">2</span>), (<span class="number">3</span>,<span class="number">1</span>), (<span class="number">5</span>,<span class="number">0</span>)]</span><br><span class="line"></span><br><span class="line">SortedL = <span class="built_in">sorted</span>(L, key=<span class="keyword">lambda</span> x: x[<span class="number">1</span>])</span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(SortedL)</span><br></pre></td></tr></table></figure><p>The result is: <code>[(5, 0), (3, 1), (1, 2)]</code>, it sorts the list based on the second element of each tuple.</p><h3 id="Standard-Solution-4"><a href="#Standard-Solution-4" class="headerlink" title="Standard Solution:"></a>Standard Solution:</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f6</span>(<span class="params">L, fields</span>):</span><br><span class="line"> <span class="keyword">return</span> <span class="built_in">sorted</span>(L, key=<span class="keyword">lambda</span> x: <span class="built_in">tuple</span>(x[i - <span class="number">1</span>] <span class="keyword">for</span> i <span class="keyword">in</span> fields))</span><br></pre></td></tr></table></figure><p><strong>Why Use a Tuple?</strong>:</p><ul><li>Tuples are often preferred for multi-key sorting because they are immutable, and Python’s built-in sorting functions can efficiently compare tuples.</li><li>Each sublist is transformed into a tuple of its elements based on the order defined by fields. The sorted() function then uses these tuples to sort the list.</li></ul>]]></content>
<summary type="html"><h1 id="Exercise-1"><a href="#Exercise-1" class="headerlink" title="Exercise 1"></a>Exercise 1</h1><h3 id="Problem-Description"><a href="#Pr</summary>
<category term="9021" scheme="https://longsizhuo.github.io/tags/9021/"/>
<category term="lab" scheme="https://longsizhuo.github.io/tags/lab/"/>
</entry>
<entry>
<title>9021_TUT_2</title>
<link href="https://longsizhuo.github.io/post/becdc081.html"/>
<id>https://longsizhuo.github.io/post/becdc081.html</id>
<published>2025-03-03T04:38:00.058Z</published>
<updated>2025-03-03T04:38:00.059Z</updated>
<content type="html"><![CDATA[<h1 id="Exercise-1"><a href="#Exercise-1" class="headerlink" title="Exercise 1:"></a>Exercise 1:</h1><p>This exercise focuses on input validation and formatting floating-point numbers. The goal is to prompt the user to enter a floating-point number between -1 and 1 (exclusive). If the input is valid, the program rounds the number to two decimal places and prints it. Otherwise, it keeps prompting the user until a valid input is provided.<br>Key Points:</p><ul><li>The program uses a try-except block to catch invalid inputs (e.g., strings that cannot be converted to floats).</li><li>The input() function is wrapped in an infinite while loop to continuously ask for input until the correct condition is met.</li></ul><p>In the updated version of Exercise 1, we use the formatting :.2f instead of round(). Here’s the key difference between the two:</p><ul><li><code>round()</code>: This is a Python built-in function that rounds a number to a specified number of decimal places. For example, round(1.236, 2) will return 1.24. However, the output of round() is still a float, but it does not guarantee a fixed number of decimal places when printed. For instance, round(1.0001, 2) would return 1.0 and only display one decimal place, not two.</li><li><code>:.2f</code>: This is part of Python’s string formatting and ensures the number is displayed with exactly two decimal places, no matter what the number is. It also rounds the number appropriately. For instance, number = 1.0 formatted as f”{number:.2f}” will print 1.00. This makes :.2f particularly useful for consistent display of decimal places, which is important for formatting output for users.</li></ul><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">while</span> <span class="literal">True</span>:</span><br><span class="line"> <span class="keyword">try</span>:</span><br><span class="line"> i = <span class="built_in">input</span>(<span class="string">'Enter a floating point number between -1 and 1 excluded: '</span>)</span><br><span class="line"> number = <span class="built_in">float</span>(i)</span><br><span class="line"> <span class="keyword">if</span> <span class="string">'.'</span> <span class="keyword">not</span> <span class="keyword">in</span> i:</span><br><span class="line"> <span class="keyword">raise</span> ValueError</span><br><span class="line"> <span class="keyword">if</span> -<span class="number">1</span> < number < <span class="number">1</span>:</span><br><span class="line"> <span class="comment"># not using round() here because it rounds to the nearest even number</span></span><br><span class="line"> <span class="built_in">print</span>(<span class="string">f'\nUp to +/-0.005, you input <span class="subst">{number:<span class="number">.2</span>f}</span>'</span>)</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> <span class="keyword">raise</span> ValueError</span><br><span class="line"> <span class="keyword">break</span></span><br><span class="line"> <span class="keyword">except</span> ValueError:</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">"You got that wrong, try again!\n"</span>)</span><br></pre></td></tr></table></figure><h1 id="Exercise-2"><a href="#Exercise-2" class="headerlink" title="Exercise 2:"></a>Exercise 2:</h1><p>This exercise involves processing a block of text and formatting it into sentences. Each sentence should have its first word capitalized, and the remaining words should be in lowercase. The task is to handle spaces and punctuation properly.</p><p>Key Points:</p><ul><li>A regular expression (re.sub) is used to replace multiple spaces with a single space.</li><li>Another regular expression (re.split) is used to split the text into sentences while preserving punctuation marks.</li><li>After splitting, the sentences are processed: the first word is capitalized, and all other words are made lowercase.</li><li>Finally, the processed sentences are recombined into a single formatted text.</li></ul><h3 id="Why-use-re-in-Exercise-2-and-what-is-re"><a href="#Why-use-re-in-Exercise-2-and-what-is-re" class="headerlink" title="Why use re in Exercise 2, and what is re?"></a>Why use re in Exercise 2, and what is re?</h3><p>In Exercise 2, we use re (Python’s regular expression module) to process and format the text input. Let’s break down why re is used and what it is:</p><h3 id="What-is-re"><a href="#What-is-re" class="headerlink" title="What is re?"></a>What is re?</h3><p>re stands for regular expressions, which are powerful tools for matching patterns in strings. The re module in Python allows you to work with regular expressions to search, split, and manipulate text based on specific patterns. Regular expressions are highly flexible and efficient for handling complex string operations.</p><h3 id="Why-use-re-in-Exercise-2"><a href="#Why-use-re-in-Exercise-2" class="headerlink" title="Why use re in Exercise 2?"></a>Why use re in Exercise 2?</h3><p>In this exercise, we need to handle several complex text manipulations:</p><ol><li>Replace multiple spaces with a single space: Sentences in the text may have irregular spaces between words, so we need to normalize these spaces. Instead of writing loops or conditions to handle each case, we use re.sub() with a pattern r’\s+’ to easily match all occurrences of one or more spaces and replace them with a single space.</li><li>Split sentences while preserving punctuation: We need to split the text into individual sentences, where each sentence is followed by punctuation (e.g., ‘.’, ‘!’, or ‘?’). The function re.split(r’([.!?])’, text) allows us to split the text based on punctuation while keeping the punctuation marks, which is crucial for proper sentence reconstruction.</li></ol><p>Regular expressions allow us to:</p><ul><li>Efficiently match patterns like spaces or punctuation.</li><li>Perform complex text transformations with minimal code.</li><li>Handle edge cases that would otherwise require more manual handling.</li></ul><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Assume that the argument text is a string that denotes a text,</span></span><br><span class="line"><span class="comment"># defined as one or more sentences, two successive</span></span><br><span class="line"><span class="comment"># sentences being separated by at least one space,</span></span><br><span class="line"><span class="comment"># the first sentence being possibly preceded with spaces,</span></span><br><span class="line"><span class="comment"># the last sentence being possibly followed by spaces,</span></span><br><span class="line"><span class="comment"># a sentence being defined as at least two words,</span></span><br><span class="line"><span class="comment"># two successive words in a sentence being separated by</span></span><br><span class="line"><span class="comment"># at least one space, a word being defined as a sequence</span></span><br><span class="line"><span class="comment"># of (uppercase or lowercase) letters,</span></span><br><span class="line"><span class="comment"># - possibly followed by a comma for a word that is</span></span><br><span class="line"><span class="comment"># not the last one in its sentence,</span></span><br><span class="line"><span class="comment"># - definitely followed by a full stop, an exclamation mark</span></span><br><span class="line"><span class="comment"># or a question mark for a word that is the last one</span></span><br><span class="line"><span class="comment"># in its sentence.</span></span><br><span class="line"><span class="keyword">import</span> re</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">f2</span>(<span class="params">text</span>):</span><br><span class="line"> <span class="comment"># Use regular expression to replace multiple spaces with a single space</span></span><br><span class="line"> text = re.sub(<span class="string">r'\s+'</span>, <span class="string">' '</span>, text.strip())</span><br><span class="line"></span><br><span class="line"> <span class="comment"># Correct way to split sentences while preserving delimiters</span></span><br><span class="line"> sentences = re.split(<span class="string">r'([.!?])'</span>, text)</span><br><span class="line"></span><br><span class="line"> <span class="comment"># Process sentences and punctuation separately</span></span><br><span class="line"> new_text = []</span><br><span class="line"> i = <span class="number">0</span></span><br><span class="line"> <span class="keyword">while</span> i < <span class="built_in">len</span>(sentences)-<span class="number">1</span>:</span><br><span class="line"> sentence = sentences[i].strip()</span><br><span class="line"> <span class="keyword">if</span> sentence:</span><br><span class="line"> sentence =<span class="string">' '</span>.join(sentence.capitalize().split())</span><br><span class="line"> <span class="comment"># Rebuild the sentence and add back the punctuation</span></span><br><span class="line"> new_text.append(sentence +sentences[i +<span class="number">1</span>])</span><br><span class="line"> i += <span class="number">2</span></span><br><span class="line"> <span class="keyword">return</span> <span class="string">' '</span>.join(new_text)</span><br></pre></td></tr></table></figure><h1 id="Exercise-3"><a href="#Exercise-3" class="headerlink" title="Exercise 3:"></a>Exercise 3:</h1><p>This exercise works with lists of integers and aims to repeatedly remove the first and last elements of the list as long as they are equal. The list is treated as a double-ended queue (deque) for efficient removal of elements from both ends.</p><p>Key Points:</p><ul><li>The deque data structure is used because it provides O(1) operations for popping elements from both ends, which is more efficient than using lists.</li><li>The program checks if the first and last elements of the deque are equal and removes them until this condition is no longer met.</li><li>The deque is converted back to a list before being returned.</li></ul><h3 id="Why-is-deque-more-efficient-than-list-in-Exercise-3"><a href="#Why-is-deque-more-efficient-than-list-in-Exercise-3" class="headerlink" title="Why is deque more efficient than list in Exercise 3?"></a>Why is <code>deque</code> more efficient than <code>list</code> in Exercise 3?</h3><p>In Exercise 3, we are frequently removing elements from both the front (left) and the back (right) of the list. This is where using a deque (double-ended queue) from Python’s collections module becomes more efficient compared to using a standard list.</p><p>Here’s why:</p><ul><li><p>List Behavior: When you use a standard list and call list.pop(0) to remove the first (leftmost) element, it requires shifting all the remaining elements one position to the left. This shift operation takes linear time—O(n), where n is the number of elements in the list. This means that for every removal from the front, the larger the list, the slower the operation becomes.</p><ul><li>Removing from the right side of a list using list.pop() is an O(1) operation (constant time) because no elements need to be shifted, making it efficient only when working from the end of the list.</li></ul></li><li><p>Deque Behavior: A deque (double-ended queue) is specifically designed to support efficient append and pop operations from both ends. In a deque, both popleft() and pop() operations take constant time—O(1)—because the deque is implemented as a doubly linked list. This means no elements need to be shifted when popping from the left or right.</p><ul><li>In Exercise 3, where we need to frequently remove elements from both ends of the list, using a deque ensures that both the removal from the left (popleft()) and the right (pop()) are performed in constant time. This makes the entire process much more efficient, especially for large lists where repeated operations would slow down if we used a standard list.</li></ul></li></ul><h3 id="What-is-a-deque"><a href="#What-is-a-deque" class="headerlink" title="What is a deque?"></a>What is a <code>deque</code>?</h3><p>A deque (short for “double-ended queue”) is a data structure that allows for fast appending and popping of elements from both ends. It is part of the collections module in Python and is optimized for scenarios where you need to efficiently add or remove elements from both ends of the sequence.</p><h3 id="Key-Features-of-deque"><a href="#Key-Features-of-deque" class="headerlink" title="Key Features of deque:"></a>Key Features of <code>deque</code>:</h3><ul><li><code>O(1)</code> time complexity for operations on both ends (append, pop, appendleft, popleft).</li><li>It is implemented as a <strong>doubly linked list</strong>, meaning each element contains a reference to both the previous and next elements, allowing efficient traversal in both directions.</li><li><code>deque</code> is ideal for scenarios where you need frequent and efficient insertions and removals from both the front and back of a sequence, unlike a standard list where such operations are costly at the front.</li></ul><h3 id="Standard-Solution"><a href="#Standard-Solution" class="headerlink" title="Standard Solution:"></a>Standard Solution:</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f3</span>(<span class="params">L</span>):</span><br><span class="line"><span class="comment"># Remove the list as long as it has at least two elements and the first and last elements are equal</span></span><br><span class="line"> <span class="keyword">while</span> <span class="built_in">len</span>(L) > <span class="number">1</span> <span class="keyword">and</span> L[<span class="number">0</span>] == L[-<span class="number">1</span>]:</span><br><span class="line"> L.pop(<span class="number">0</span>) <span class="comment"># Remove the first element</span></span><br><span class="line"> L.pop(-<span class="number">1</span>) <span class="comment"># Remove the last element</span></span><br><span class="line"> <span class="keyword">return</span> L</span><br><span class="line"></span><br></pre></td></tr></table></figure><h3 id="My-Solution"><a href="#My-Solution" class="headerlink" title="My Solution:"></a>My Solution:</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> collections <span class="keyword">import</span> deque</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">f3</span>(<span class="params">L</span>):</span><br><span class="line"> L = deque(L) <span class="comment"># Convert the list to a deque for efficient popping from both ends</span></span><br><span class="line"> <span class="comment"># Continue removing elements while there are at least two elements and the first and last are equal</span></span><br><span class="line"> <span class="keyword">while</span> <span class="built_in">len</span>(L) > <span class="number">1</span> <span class="keyword">and</span> L[<span class="number">0</span>] == L[-<span class="number">1</span>]:</span><br><span class="line"> L.popleft() <span class="comment"># Efficiently remove the first element (O(1) operation)</span></span><br><span class="line"> L.pop() <span class="comment"># Efficiently remove the last element (O(1) operation)</span></span><br><span class="line"> <span class="keyword">return</span> <span class="built_in">list</span>(L) <span class="comment"># Convert the deque back to a list and return it</span></span><br></pre></td></tr></table></figure><h1 id="Exercise-4"><a href="#Exercise-4" class="headerlink" title="Exercise 4:"></a>Exercise 4:</h1><p>This exercise deals with lists of integers that are in increasing order. The goal is to remove any element whose value is equal to its index in the list. The program iterates over the list and removes such elements, ensuring the index is correctly adjusted after each removal.</p><p>Key Points:</p><ul><li>The program uses a while loop and checks if the element at index i is equal to i. If true, it removes the element and does not increment i, so that the next element at the same position is checked.</li><li>The remove() function is used to delete the element, which is appropriate for this task.</li><li>Care is taken to ensure that index adjustments are handled correctly.</li></ul><p>The reason we use remove() instead of pop(0) or popleft() in a deque is that we need to specifically remove the value that matches the number we reached. pop() and popleft() remove elements by position, without considering the value, which isn’t suitable for our case.</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Assume that the argument L is a list of integers</span></span><br><span class="line"><span class="comment"># that forms an increasing sequence.</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># For as long as some member of the list is equal to its index</span></span><br><span class="line"><span class="comment"># in the list, pop out the leftmost such member of the list.</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">f4</span>(<span class="params">L</span>):</span><br><span class="line"> i = <span class="number">0</span></span><br><span class="line"> <span class="keyword">while</span> i < <span class="built_in">len</span>(L):</span><br><span class="line"> <span class="keyword">if</span> L[i] == i:</span><br><span class="line"> L.remove(L[i]) <span class="comment"># Using remove() here since popleft() removes from the left only</span></span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> i += <span class="number">1</span> <span class="comment"># Only increment i if no element was removed</span></span><br><span class="line"> <span class="keyword">return</span> L</span><br></pre></td></tr></table></figure><h1 id="Exercise-5"><a href="#Exercise-5" class="headerlink" title="Exercise 5:"></a>Exercise 5:</h1><p>This exercise works with a circular list of integers. The task is to identify elements that are both larger than one of their adjacent elements and smaller than the other. The result is returned as a dictionary where each key is such an element, and its value is a pair of the adjacent elements (one smaller and one larger).</p><p>Key Points:</p><ul><li>The list is treated as circular, meaning the first element is considered adjacent to the last element.</li><li>The program iterates through the list, compares each element with its neighbors, and stores those that meet the criteria.</li><li>For each valid element, the adjacent smaller and larger elements are stored in a dictionary.</li></ul><p>To solve this problem, we need to create a dictionary D where each key is an element in the list L that satisfies a certain condition, and the value is a tuple of two elements. The first element of this tuple is the adjacent element that is smaller than the current key, and the second element is the adjacent element that is larger than the current key.</p><p>Steps:</p><ol><li>Loop structure: Check each element.</li><li>Processing of adjacent elements: Since the list is cyclic, the previous element of the first element is the last element, and the next element of the last element is the first element.</li><li>Condition check: Find the adjacent elements that are smaller and larger than the current element, and add them to the result dictionary.</li></ol><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Assume that the argument L is a list of at least 3 distinct integers.</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># Returns a dictionary D whose keys are those of the members e of L,</span></span><br><span class="line"><span class="comment"># if any, that are</span></span><br><span class="line"><span class="comment"># - smaller than the element right before or right after, and</span></span><br><span class="line"><span class="comment"># - larger than the element right before or right after.</span></span><br><span class="line"><span class="comment"># It is considered that</span></span><br><span class="line"><span class="comment"># - the first member of L is right after the last member of L, and</span></span><br><span class="line"><span class="comment"># - the last member of L is right before the first member of L</span></span><br><span class="line"><span class="comment"># (as if making a ring out of the list).</span></span><br><span class="line"><span class="comment"># For a key e in D, the associated value is the pair whose</span></span><br><span class="line"><span class="comment"># first element is the member of L that is right before or right after</span></span><br><span class="line"><span class="comment"># e and smaller than e, and whose second element is the member of L</span></span><br><span class="line"><span class="comment"># that is right before or right after e and greater than e.</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">f5</span>(<span class="params">L</span>):</span><br><span class="line"> D = {}</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="built_in">len</span>(L)):</span><br><span class="line"> m = L[i - <span class="number">1</span>]</span><br><span class="line"> n = L[(i + <span class="number">1</span>) % <span class="built_in">len</span>(L)]</span><br><span class="line"> <span class="keyword">if</span> n < m:</span><br><span class="line"> m, n = n, m</span><br><span class="line"> <span class="keyword">if</span> m < L[i] < n:</span><br><span class="line"> D[L[i]] = m, n</span><br><span class="line"> <span class="keyword">return</span> D</span><br></pre></td></tr></table></figure><h1 id="Exercise-6"><a href="#Exercise-6" class="headerlink" title="Exercise 6:"></a>Exercise 6:</h1><p>This exercise deals with factorizing an integer n into the form 2^k * m, where m is an odd number. If n is negative, the program adds a negative sign to the output. If n is zero, it prints a special message.</p><p>Key Points:</p><ul><li>The program uses a loop to divide n by 2 until n is no longer divisible by 2, counting the number of divisions (k).</li><li>The absolute value of n is used to ensure correct handling of negative numbers, and a sign is added to the final result if the original number was negative.</li><li>The program handles the special case where n = 0 by printing a unique message.</li></ul><p>More Details:</p><ol><li>You need to express the given integer n as n = 2^k * m.<ul><li>k represents the number of times n can be divided by 2. In other words, it is the power of 2 in the factorization of n.</li><li>m is the remaining odd part after dividing out all factors of 2.</li></ul></li><li>If n is negative, the output should include a negative sign.</li><li>Special case: If n = 0, a specific message should be printed.</li><li>The result is printed directly, not returned.</li></ol><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Assume that the argument n is an integer.</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># The output is printed out, not returned.</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># You might find the abs() function useful.</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">f6</span>(<span class="params">n</span>):</span><br><span class="line"> <span class="keyword">if</span> n == <span class="number">0</span>:</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">"0 = 2^k * 0 for all integers k!"</span>)</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> k = <span class="number">0</span></span><br><span class="line"> ori = n</span><br><span class="line"> <span class="keyword">if</span> n < <span class="number">0</span>:</span><br><span class="line"> sign = <span class="string">'-'</span></span><br><span class="line"> n = -n</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> sign = <span class="string">''</span></span><br><span class="line"> <span class="keyword">while</span> n % <span class="number">2</span> == <span class="number">0</span>:</span><br><span class="line"> n //= <span class="number">2</span></span><br><span class="line"> k += <span class="number">1</span></span><br><span class="line"> <span class="built_in">print</span>(<span class="string">f"<span class="subst">{ori}</span> = <span class="subst">{sign}</span>2^<span class="subst">{k}</span> * <span class="subst">{n}</span>"</span>)</span><br><span class="line"> <span class="keyword">return</span></span><br></pre></td></tr></table></figure><p><strong>FOR VERY VERY VERY VERY VERY BIG NUMBER:</strong></p><p>When dealing with very large integers, the method of continuously dividing the number by 2 to factor out powers of 2 (2^k) can become inefficient. This is because each division can be costly in terms of computational time, especially for very large numbers with millions or billions of digits. Each division involves recalculating the entire integer, which is slow for large integers.<br>Using Bit Manipulation:</p><p>A much more efficient approach is to use <strong>bit manipulation</strong> to determine how many times a number can be divided by 2 (i.e., how many factors of 2 it has). This method avoids division altogether and instead directly analyzes the binary representation of the number to count the number of trailing zeros, which correspond to the powers of 2 in the factorization.</p><h3 id="Why"><a href="#Why" class="headerlink" title="Why?"></a>Why?</h3><ol><li><p>Bitwise operations are much faster than arithmetic operations like division, especially for large integers. Counting the trailing zeros in a number’s binary representation can be done in constant time.</p></li><li><p>Extracting the lowest set bit of a number allows us to quickly find how many times a number can be divided by 2 without having to repeatedly divide the number. This provides the power of 2 (k) directly.</p></li></ol><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f6</span>(<span class="params">n</span>):</span><br><span class="line"> <span class="keyword">if</span> n == <span class="number">0</span>:</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">"0 = 2^k * 0 for all integers k!"</span>)</span><br><span class="line"> <span class="keyword">return</span></span><br><span class="line"> </span><br><span class="line"> <span class="comment"># Handle negative sign</span></span><br><span class="line"> sign = <span class="string">'-'</span> <span class="keyword">if</span> n < <span class="number">0</span> <span class="keyword">else</span> <span class="string">''</span></span><br><span class="line"> n = <span class="built_in">abs</span>(n)</span><br><span class="line"> </span><br><span class="line"> <span class="comment"># Using bit manipulation to count how many trailing zeros (powers of 2)</span></span><br><span class="line"> k = (n & -n).bit_length() - <span class="number">1</span> <span class="comment"># Count trailing zeros by isolating the lowest set bit</span></span><br><span class="line"> </span><br><span class="line"> <span class="comment"># Remove 2^k factor from n</span></span><br><span class="line"> m = n >> k <span class="comment"># Equivalent to n // 2^k, shifting right by k bits</span></span><br><span class="line"> </span><br><span class="line"> <span class="comment"># Print the result</span></span><br><span class="line"> <span class="built_in">print</span>(<span class="string">f"<span class="subst">{sign}</span><span class="subst">{n}</span> = <span class="subst">{sign}</span>2^<span class="subst">{k}</span> * <span class="subst">{m}</span>"</span>)</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html"><h1 id="Exercise-1"><a href="#Exercise-1" class="headerlink" title="Exercise 1:"></a>Exercise 1:</h1><p>This exercise focuses on input valid</summary>
<category term="Python" scheme="https://longsizhuo.github.io/tags/Python/"/>
<category term="Tutorial" scheme="https://longsizhuo.github.io/tags/Tutorial/"/>
</entry>
<entry>
<title>9021_TUT_1_25T1</title>
<link href="https://longsizhuo.github.io/post/b9bbc455.html"/>
<id>https://longsizhuo.github.io/post/b9bbc455.html</id>
<published>2025-03-03T04:38:00.024Z</published>
<updated>2025-03-03T04:38:00.183Z</updated>
<content type="html"><![CDATA[<h1 id="Introduction-How-Labs-work"><a href="#Introduction-How-Labs-work" class="headerlink" title="Introduction How Labs work"></a>Introduction How Labs work</h1><p>We can see the structure of the lab is like this:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_">%</span><span class="language-bash">%run_and_test python3 -c <span class="string">"from exercise_1_1 import f1; print(f1(0, 0))"</span></span></span><br><span class="line"></span><br><span class="line">'\n'</span><br></pre></td></tr></table></figure><p>Which means <code>run_and_test</code> ? It is a Magic Command, run python file which is <code>exercise_1_1.py</code> and test the output of <code>f1(0, 0)</code>.</p><p>And at the top of this Jupyter notebook, we can see the following code:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">load_ext run_and_test</span><br></pre></td></tr></table></figure><p>This is a magic command that loads the <code>run_and_test</code> extension, which allows us to run and test Python code in the notebook.</p><p>And if you run <code>%pycat exercise_1_1_template.py</code>, you will get a new file <code>exercise_1_1.py</code> which is the template of the exercise.</p><p>You can write your code inside the <code>exercise_1_1.py</code> file and run the test code in the notebook to check if your code is correct. Or directly write your code after <code>%%writefile exercise_1_1.py</code> command block.</p><h1 id="Exercise-1"><a href="#Exercise-1" class="headerlink" title="Exercise 1"></a>Exercise 1</h1><p>Finding the pattern, we can see that the first parameter m means how many structures there are, and the second parameter n means how many underscores there are.</p><p>So we can assume the structure is like:</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">|____|</span><br></pre></td></tr></table></figure><p>And if we have <code>m = 3</code> and <code>n = 4</code>, the output would be:</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">|____||____||____|</span><br></pre></td></tr></table></figure><h3 id="My-solution"><a href="#My-solution" class="headerlink" title="My solution"></a>My solution</h3><p>In Python, we can use multiplication to repeat a string. So we can use the following code to solve this problem:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f1</span>(<span class="params">m, n</span>):</span><br><span class="line"> <span class="keyword">return</span> (<span class="string">'|'</span> + <span class="string">'_'</span> * n + <span class="string">'|'</span>) * m</span><br></pre></td></tr></table></figure><h1 id="Exercise-2"><a href="#Exercise-2" class="headerlink" title="Exercise 2"></a>Exercise 2</h1><p>Same way to find the pattern, n rows and n columns, and each row contains the digit n repeated n times.</p><p>And you can find, the input <code>n</code> is a digit, which means it is an integer. While we use “*” with the integer, it is the mathematical multiplication.</p><p>So we need to convert the integer to a string, and then multiply it with the integer, and add a newline at the end of each row.</p><h3 id="My-solution-1"><a href="#My-solution-1" class="headerlink" title="My solution"></a>My solution</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f2</span>(<span class="params">n</span>):</span><br><span class="line"> <span class="keyword">return</span> (<span class="built_in">str</span>(n)*n + <span class="string">"\n"</span>)*n</span><br></pre></td></tr></table></figure><p>And… in case you want to use a for loop:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f2</span>(<span class="params">n</span>):</span><br><span class="line"> result = <span class="string">""</span></span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(n):</span><br><span class="line"> result += <span class="built_in">str</span>(n) * n + <span class="string">"\n"</span></span><br><span class="line"> <span class="keyword">return</span> result</span><br></pre></td></tr></table></figure><h1 id="Exercise-3"><a href="#Exercise-3" class="headerlink" title="Exercise 3"></a>Exercise 3</h1><p>This problem is a bit complex to understand, so let’s break it down step by step. Based on Eric’s reply in Ed, we can see that the problem requires us to traverse from the rightmost side, removing all elements that are ≤ the last element (<code>x</code>) until we encounter a number that is ≥ the last element (<code>y</code>). It is important to note that if there are any elements to the left of <code>y</code> that were previously removed, they should also be removed.</p><p>This Exercise needs us use only 1 loop.</p><h3 id="My-solution-2"><a href="#My-solution-2" class="headerlink" title="My solution"></a>My solution</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f3</span>(<span class="params">L</span>):</span><br><span class="line"> <span class="comment"># You can use [] list here, but set is more effective</span></span><br><span class="line"> num_remove = <span class="built_in">set</span>()</span><br><span class="line"> <span class="comment"># Check ED of Eric's reply</span></span><br><span class="line"> i = <span class="built_in">len</span>(L)-<span class="number">2</span></span><br><span class="line"> flag = <span class="number">0</span></span><br><span class="line"> <span class="keyword">while</span> i >= <span class="number">0</span>:</span><br><span class="line"> <span class="keyword">if</span> L[i] < L[-<span class="number">1</span>] <span class="keyword">and</span> flag == <span class="number">0</span>:</span><br><span class="line"> num_remove.add(L[i])</span><br><span class="line"> L.pop(i)</span><br><span class="line"> <span class="comment"># reset the length in case it have nothing</span></span><br><span class="line"> i = <span class="built_in">len</span>(L) - <span class="number">2</span></span><br><span class="line"> <span class="keyword">elif</span> L[i] >= L[-<span class="number">1</span>]:</span><br><span class="line"> i -= <span class="number">1</span></span><br><span class="line"> flag = <span class="number">1</span></span><br><span class="line"> <span class="keyword">elif</span> L[i] <span class="keyword">in</span> num_remove:</span><br><span class="line"> L.pop(i)</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> i -= <span class="number">1</span></span><br><span class="line"> <span class="built_in">print</span>(L)</span><br></pre></td></tr></table></figure><div class="video-container"><iframe src=https://www.youtube.com/embed/YgEypL0B7Dc?si=I6HzsdgN1axAoGLT frameborder=0 allow=encrypted-media allowfullscreen></iframe></div><pre><code>You can full screen, change speed, and change quality of the video.</code></pre><h3 id="Standard-Solution"><a href="#Standard-Solution" class="headerlink" title="Standard Solution"></a>Standard Solution</h3><p>I have to say Eric is a genius:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f3</span>(<span class="params">L</span>):</span><br><span class="line"> <span class="keyword">while</span> <span class="built_in">len</span>(L) > <span class="number">1</span> <span class="keyword">and</span> L[-<span class="number">2</span>] < L[-<span class="number">1</span>]:</span><br><span class="line"> L.remove(L[-<span class="number">2</span>])</span><br><span class="line"> <span class="built_in">print</span>(L)</span><br></pre></td></tr></table></figure><div class="video-container"><iframe src=https://www.youtube.com/embed/hkcVLv-1U-Q?si=pB4HqSilD_T7h1bj frameborder=0 allow=encrypted-media allowfullscreen></iframe></div><pre><code>You can full screen, change speed, and change quality of the video.</code></pre><h1 id="Exercise-4"><a href="#Exercise-4" class="headerlink" title="Exercise 4"></a>Exercise 4</h1><p>The fourth function, f4, works with dictionaries:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f4</span>(<span class="params">D, n</span>):</span><br><span class="line"> <span class="keyword">if</span> n <span class="keyword">not</span> <span class="keyword">in</span> D:</span><br><span class="line"> <span class="keyword">return</span> []</span><br><span class="line"> ans = [n]</span><br><span class="line"> <span class="keyword">while</span> n <span class="keyword">in</span> D <span class="keyword">and</span> D[n] > n:</span><br><span class="line"> ans.append(D[n])</span><br><span class="line"> n = D[n]</span><br><span class="line"> <span class="keyword">return</span> ans</span><br></pre></td></tr></table></figure><ol><li>This function takes a dictionary D and an integer n. It generates a strictly increasing sequence of integers based on the relationships defined in the dictionary.</li><li>Starting from n, it appends D[n], D[D[n]], and so on to the list, as long as each subsequent value is greater than the previous one.</li><li>For example, if D = {1: 2, 2: 3, 3: 5} and n = 1, the function will return [1, 2, 3, 5].</li></ol><h3 id="Standard-Solution-1"><a href="#Standard-Solution-1" class="headerlink" title="Standard Solution"></a>Standard Solution</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f4</span>(<span class="params">D, n</span>):</span><br><span class="line"> L = [] <span class="keyword">if</span> n <span class="keyword">not</span> <span class="keyword">in</span> D <span class="keyword">else</span> [n]</span><br><span class="line"> <span class="keyword">while</span> n <span class="keyword">in</span> D <span class="keyword">and</span> n < D[n]:</span><br><span class="line"> L.append(D[n])</span><br><span class="line"> n = D[n]</span><br><span class="line"> <span class="keyword">return</span> L</span><br></pre></td></tr></table></figure><h1 id="Exercise-5"><a href="#Exercise-5" class="headerlink" title="Exercise 5"></a>Exercise 5</h1><p>The fifth function, f5, reads from a file and processes each line:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f5</span>(<span class="params">filename</span>):</span><br><span class="line"> <span class="keyword">with</span> <span class="built_in">open</span>(filename) <span class="keyword">as</span> f:</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> f:</span><br><span class="line"> name, number = i.split(<span class="string">','</span>)</span><br><span class="line"> number = <span class="built_in">int</span>(number) * <span class="number">1000</span></span><br><span class="line"> <span class="built_in">print</span>(<span class="string">f"<span class="subst">{number}</span> people named <span class="subst">{name}</span>"</span>)</span><br></pre></td></tr></table></figure><ol><li>This function reads a text file, where each line consists of a name and a count separated by a comma.</li><li>The function multiplies the count by 1000 and prints the result in the format: “X people named Y”.</li><li>For example, if the file contains a line “John,5”, it will print:</li></ol><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">5000 people named John</span><br></pre></td></tr></table></figure><h3 id="Standard-Solution-2"><a href="#Standard-Solution-2" class="headerlink" title="Standard Solution"></a>Standard Solution</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f5</span>(<span class="params">filename</span>):</span><br><span class="line"> <span class="keyword">with</span> <span class="built_in">open</span>(filename) <span class="keyword">as</span> file:</span><br><span class="line"> <span class="keyword">for</span> line <span class="keyword">in</span> file:</span><br><span class="line"> name, count = line.split(<span class="string">','</span>)</span><br><span class="line"> <span class="built_in">print</span>(<span class="built_in">int</span>(count) * <span class="number">1_000</span>, <span class="string">'people named'</span>, name)</span><br></pre></td></tr></table></figure><h1 id="Exercise-6"><a href="#Exercise-6" class="headerlink" title="Exercise 6"></a>Exercise 6</h1><p>The final function, f6, also reads from a text file, but with a different format:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f6</span>(<span class="params">filename</span>):</span><br><span class="line"> <span class="keyword">with</span> <span class="built_in">open</span>(filename) <span class="keyword">as</span> f:</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> f:</span><br><span class="line"> <span class="comment"># Check if the line is not empty</span></span><br><span class="line"> <span class="keyword">if</span> <span class="keyword">not</span> i.isspace():</span><br><span class="line"> number, charactor = i.split()</span><br><span class="line"> <span class="built_in">print</span>(<span class="built_in">int</span>(number) * charactor)</span><br></pre></td></tr></table></figure><ol><li>This function reads lines that contain an integer followed by a symbol (e.g., “5 *”).</li><li>It multiplies the symbol by the integer and prints the result.</li><li>For example, if the file contains the line “3 # “, the function will print:</li></ol><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">### </span><br></pre></td></tr></table></figure>]]></content>
<summary type="html"><h1 id="Introduction-How-Labs-work"><a href="#Introduction-How-Labs-work" class="headerlink" title="Introduction How Labs work"></a>Introduc</summary>
<category term="“9021”" scheme="https://longsizhuo.github.io/tags/%E2%80%9C9021%E2%80%9D/"/>
<category term="Tutorial" scheme="https://longsizhuo.github.io/tags/Tutorial/"/>
<category term="Lab" scheme="https://longsizhuo.github.io/tags/Lab/"/>
</entry>
<entry>
<title>9021_TUT_2_25T1</title>
<link href="https://longsizhuo.github.io/post/8036f890.html"/>
<id>https://longsizhuo.github.io/post/8036f890.html</id>
<published>2025-02-02T13:00:00.000Z</published>
<updated>2025-03-12T03:10:41.124Z</updated>
<content type="html"><![CDATA[<h1 id="Exercise-1"><a href="#Exercise-1" class="headerlink" title="Exercise 1:"></a>Exercise 1:</h1><p>This exercise focuses on input validation and formatting floating-point numbers. The goal is to prompt the user to enter a floating-point number between -1 and 1 (exclusive). If the input is valid, the program rounds the number to two decimal places and prints it. Otherwise, it keeps prompting the user until a valid input is provided.<br>Key Points:</p><ul><li>The program uses a try-except block to catch invalid inputs (e.g., strings that cannot be converted to floats).</li><li>The input() function is wrapped in an infinite while loop to continuously ask for input until the correct condition is met.</li></ul><p>In the updated version of Exercise 1, we use the formatting :.2f instead of round(). Here’s the key difference between the two:</p><ul><li><code>round()</code>: This is a Python built-in function that rounds a number to a specified number of decimal places. For example, round(1.236, 2) will return 1.24. However, the output of round() is still a float, but it does not guarantee a fixed number of decimal places when printed. For instance, round(1.0001, 2) would return 1.0 and only display one decimal place, not two.</li><li><code>:.2f</code>: This is part of Python’s string formatting and ensures the number is displayed with exactly two decimal places, no matter what the number is. It also rounds the number appropriately. For instance, number = 1.0 formatted as f”{number:.2f}” will print 1.00. This makes :.2f particularly useful for consistent display of decimal places, which is important for formatting output for users.</li></ul><h3 id="My-Solution"><a href="#My-Solution" class="headerlink" title="My Solution"></a>My Solution</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">while</span> <span class="literal">True</span>:</span><br><span class="line"> <span class="keyword">try</span>:</span><br><span class="line"> i = <span class="built_in">input</span>(<span class="string">'Enter a floating point number between -1 and 1 excluded: '</span>)</span><br><span class="line"> number = <span class="built_in">float</span>(i)</span><br><span class="line"> <span class="keyword">if</span> <span class="string">'.'</span> <span class="keyword">not</span> <span class="keyword">in</span> i:</span><br><span class="line"> <span class="keyword">raise</span> ValueError</span><br><span class="line"> <span class="keyword">if</span> -<span class="number">1</span> < number < <span class="number">1</span>:</span><br><span class="line"> <span class="comment"># not using round() here because it rounds to the nearest even number</span></span><br><span class="line"> <span class="built_in">print</span>(<span class="string">f'\nUp to +/-0.005, you input <span class="subst">{number:<span class="number">.2</span>f}</span>'</span>)</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> <span class="keyword">raise</span> ValueError</span><br><span class="line"> <span class="keyword">break</span></span><br><span class="line"> <span class="keyword">except</span> ValueError:</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">"You got that wrong, try again!\n"</span>)</span><br></pre></td></tr></table></figure><h3 id="Standard-Solution"><a href="#Standard-Solution" class="headerlink" title="Standard Solution"></a>Standard Solution</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">while</span> <span class="literal">True</span>:</span><br><span class="line"> <span class="keyword">try</span>:</span><br><span class="line"> x = <span class="built_in">input</span>(<span class="string">'Enter a floating point number between -1 and 1 excluded: '</span>)</span><br><span class="line"> <span class="keyword">if</span> <span class="string">'.'</span> <span class="keyword">not</span> <span class="keyword">in</span> x:</span><br><span class="line"> <span class="keyword">raise</span> ValueError</span><br><span class="line"> x = <span class="built_in">float</span>(x)</span><br><span class="line"> <span class="keyword">if</span> <span class="keyword">not</span> (-<span class="number">1</span> < x < <span class="number">1</span>):</span><br><span class="line"> <span class="keyword">raise</span> ValueError</span><br><span class="line"> <span class="keyword">break</span></span><br><span class="line"> <span class="keyword">except</span> ValueError:</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">'You got that wrong, try again!\n'</span>)</span><br><span class="line"><span class="built_in">print</span>(<span class="string">f'\nUp to +/-0.005, you input <span class="subst">{x:<span class="number">.2</span>f}</span>'</span>)</span><br></pre></td></tr></table></figure><h1 id="Exercise-2"><a href="#Exercise-2" class="headerlink" title="Exercise 2:"></a>Exercise 2:</h1><p>This exercise involves processing a block of text and formatting it into sentences. Each sentence should have its first word capitalized, and the remaining words should be in lowercase. The task is to handle spaces and punctuation properly.</p><p>In other words: <strong>Modify the sentence to conform to English grammar</strong></p><h1 id="Standard-Solution-1"><a href="#Standard-Solution-1" class="headerlink" title="Standard Solution"></a>Standard Solution</h1><ol><li>Split <code>text</code> into a list of words.</li><li>Iterate through the words and apply the following rules:<ul><li>If the word is the first word of the sentence (i.e., the first word or follows a sentence-ending punctuation mark), capitalize it.</li><li>If the word is not the first word of the sentence, make it lowercase.</li></ul></li></ol><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f2</span>(<span class="params">text</span>):</span><br><span class="line"> words = text.split()</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="built_in">len</span>(words)):</span><br><span class="line"> <span class="comment"># Ternary Expression</span></span><br><span class="line"> words[i] = words[i].title() <span class="keyword">if</span> i == <span class="number">0</span> <span class="keyword">or</span> words[i - <span class="number">1</span>][-<span class="number">1</span>] <span class="keyword">in</span> <span class="string">'.!?'</span>\</span><br><span class="line"> <span class="keyword">else</span> words[i].lower()</span><br><span class="line"> <span class="keyword">return</span> <span class="string">' '</span>.join(words)</span><br></pre></td></tr></table></figure><p>Key Points:</p><ul><li>A regular expression (re.sub) is used to replace multiple spaces with a single space.</li><li>Another regular expression (re.split) is used to split the text into sentences while preserving punctuation marks.</li><li>After splitting, the sentences are processed: the first word is capitalized, and all other words are made lowercase.</li><li>Finally, the processed sentences are recombined into a single formatted text.</li></ul><h3 id="Why-use-re-in-Exercise-2-and-what-is-re"><a href="#Why-use-re-in-Exercise-2-and-what-is-re" class="headerlink" title="Why use re in Exercise 2, and what is re?"></a>Why use re in Exercise 2, and what is re?</h3><p>In Exercise 2, we use re (Python’s regular expression module) to process and format the text input. Let’s break down why re is used and what it is:</p><h3 id="What-is-re"><a href="#What-is-re" class="headerlink" title="What is re?"></a>What is re?</h3><p>re stands for regular expressions, which are powerful tools for matching patterns in strings. The re module in Python allows you to work with regular expressions to search, split, and manipulate text based on specific patterns. Regular expressions are highly flexible and efficient for handling complex string operations.</p><h3 id="Why-use-re-in-Exercise-2"><a href="#Why-use-re-in-Exercise-2" class="headerlink" title="Why use re in Exercise 2?"></a>Why use re in Exercise 2?</h3><p>In this exercise, we need to handle several complex text manipulations:</p><ol><li>Replace multiple spaces with a single space: Sentences in the text may have irregular spaces between words, so we need to normalize these spaces. Instead of writing loops or conditions to handle each case, we use re.sub() with a pattern r’\s+’ to easily match all occurrences of one or more spaces and replace them with a single space.</li><li>Split sentences while preserving punctuation: We need to split the text into individual sentences, where each sentence is followed by punctuation (e.g., ‘.’, ‘!’, or ‘?’). The function re.split(r’([.!?])’, text) allows us to split the text based on punctuation while keeping the punctuation marks, which is crucial for proper sentence reconstruction.</li></ol><p>Regular expressions allow us to:</p><ul><li>Efficiently match patterns like spaces or punctuation.</li><li>Perform complex text transformations with minimal code.</li><li>Handle edge cases that would otherwise require more manual handling.</li></ul><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Assume that the argument text is a string that denotes a text,</span></span><br><span class="line"><span class="comment"># defined as one or more sentences, two successive</span></span><br><span class="line"><span class="comment"># sentences being separated by at least one space,</span></span><br><span class="line"><span class="comment"># the first sentence being possibly preceded with spaces,</span></span><br><span class="line"><span class="comment"># the last sentence being possibly followed by spaces,</span></span><br><span class="line"><span class="comment"># a sentence being defined as at least two words,</span></span><br><span class="line"><span class="comment"># two successive words in a sentence being separated by</span></span><br><span class="line"><span class="comment"># at least one space, a word being defined as a sequence</span></span><br><span class="line"><span class="comment"># of (uppercase or lowercase) letters,</span></span><br><span class="line"><span class="comment"># - possibly followed by a comma for a word that is</span></span><br><span class="line"><span class="comment"># not the last one in its sentence,</span></span><br><span class="line"><span class="comment"># - definitely followed by a full stop, an exclamation mark</span></span><br><span class="line"><span class="comment"># or a question mark for a word that is the last one</span></span><br><span class="line"><span class="comment"># in its sentence.</span></span><br><span class="line"><span class="keyword">import</span> re</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">f2</span>(<span class="params">text</span>):</span><br><span class="line"> <span class="comment"># Use regular expression to replace multiple spaces with a single space</span></span><br><span class="line"> text = re.sub(<span class="string">r'\s+'</span>, <span class="string">' '</span>, text.strip())</span><br><span class="line"></span><br><span class="line"> <span class="comment"># Correct way to split sentences while preserving delimiters</span></span><br><span class="line"> sentences = re.split(<span class="string">r'([.!?])'</span>, text)</span><br><span class="line"></span><br><span class="line"> <span class="comment"># Process sentences and punctuation separately</span></span><br><span class="line"> new_text = []</span><br><span class="line"> i = <span class="number">0</span></span><br><span class="line"> <span class="keyword">while</span> i < <span class="built_in">len</span>(sentences)-<span class="number">1</span>:</span><br><span class="line"> sentence = sentences[i].strip()</span><br><span class="line"> <span class="keyword">if</span> sentence:</span><br><span class="line"> sentence =<span class="string">' '</span>.join(sentence.capitalize().split())</span><br><span class="line"> <span class="comment"># Rebuild the sentence and add back the punctuation</span></span><br><span class="line"> new_text.append(sentence +sentences[i +<span class="number">1</span>])</span><br><span class="line"> i += <span class="number">2</span></span><br><span class="line"> <span class="keyword">return</span> <span class="string">' '</span>.join(new_text)</span><br></pre></td></tr></table></figure><h1 id="Exercise-3"><a href="#Exercise-3" class="headerlink" title="Exercise 3:"></a>Exercise 3:</h1><p>This exercise works with lists of integers and aims to repeatedly remove the first and last elements of the list as long as they are equal. The list is treated as a double-ended queue (deque) for efficient removal of elements from both ends.</p><p>Key Points:</p><ul><li>The deque data structure is used because it provides O(1) operations for popping elements from both ends, which is more efficient than using lists.</li><li>The program checks if the first and last elements of the deque are equal and removes them until this condition is no longer met.</li><li>The deque is converted back to a list before being returned.</li></ul><h3 id="Why-is-deque-more-efficient-than-list-in-Exercise-3"><a href="#Why-is-deque-more-efficient-than-list-in-Exercise-3" class="headerlink" title="Why is deque more efficient than list in Exercise 3?"></a>Why is <code>deque</code> more efficient than <code>list</code> in Exercise 3?</h3><p>In Exercise 3, we are frequently removing elements from both the front (left) and the back (right) of the list. This is where using a deque (double-ended queue) from Python’s collections module becomes more efficient compared to using a standard list.</p><p>Here’s why:</p><ul><li><p>List Behavior: When you use a standard list and call list.pop(0) to remove the first (leftmost) element, it requires shifting all the remaining elements one position to the left. This shift operation takes linear time—O(n), where n is the number of elements in the list. This means that for every removal from the front, the larger the list, the slower the operation becomes.</p><ul><li>Removing from the right side of a list using list.pop() is an O(1) operation (constant time) because no elements need to be shifted, making it efficient only when working from the end of the list.</li></ul></li><li><p>Deque Behavior: A deque (double-ended queue) is specifically designed to support efficient append and pop operations from both ends. In a deque, both popleft() and pop() operations take constant time—O(1)—because the deque is implemented as a doubly linked list. This means no elements need to be shifted when popping from the left or right.</p><ul><li>In Exercise 3, where we need to frequently remove elements from both ends of the list, using a deque ensures that both the removal from the left (popleft()) and the right (pop()) are performed in constant time. This makes the entire process much more efficient, especially for large lists where repeated operations would slow down if we used a standard list.</li></ul></li></ul><h3 id="What-is-a-deque"><a href="#What-is-a-deque" class="headerlink" title="What is a deque?"></a>What is a <code>deque</code>?</h3><p>A deque (short for “double-ended queue”) is a data structure that allows for fast appending and popping of elements from both ends. It is part of the collections module in Python and is optimized for scenarios where you need to efficiently add or remove elements from both ends of the sequence.</p><h3 id="Key-Features-of-deque"><a href="#Key-Features-of-deque" class="headerlink" title="Key Features of deque:"></a>Key Features of <code>deque</code>:</h3><ul><li><code>O(1)</code> time complexity for operations on both ends (append, pop, appendleft, popleft).</li><li>It is implemented as a <strong>doubly linked list</strong>, meaning each element contains a reference to both the previous and next elements, allowing efficient traversal in both directions.</li><li><code>deque</code> is ideal for scenarios where you need frequent and efficient insertions and removals from both the front and back of a sequence, unlike a standard list where such operations are costly at the front.</li></ul><h3 id="Standard-Solution-2"><a href="#Standard-Solution-2" class="headerlink" title="Standard Solution:"></a>Standard Solution:</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f3</span>(<span class="params">L</span>):</span><br><span class="line"><span class="comment"># Remove the list as long as it has at least two elements and the first and last elements are equal</span></span><br><span class="line"> <span class="keyword">while</span> <span class="built_in">len</span>(L) > <span class="number">1</span> <span class="keyword">and</span> L[<span class="number">0</span>] == L[-<span class="number">1</span>]:</span><br><span class="line"> L.pop(<span class="number">0</span>) <span class="comment"># Remove the first element</span></span><br><span class="line"> L.pop(-<span class="number">1</span>) <span class="comment"># Remove the last element</span></span><br><span class="line"> <span class="keyword">return</span> L</span><br><span class="line"></span><br></pre></td></tr></table></figure><h3 id="My-Solution-1"><a href="#My-Solution-1" class="headerlink" title="My Solution:"></a>My Solution:</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> collections <span class="keyword">import</span> deque</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">f3</span>(<span class="params">L</span>):</span><br><span class="line"> L = deque(L) <span class="comment"># Convert the list to a deque for efficient popping from both ends</span></span><br><span class="line"> <span class="comment"># Continue removing elements while there are at least two elements and the first and last are equal</span></span><br><span class="line"> <span class="keyword">while</span> <span class="built_in">len</span>(L) > <span class="number">1</span> <span class="keyword">and</span> L[<span class="number">0</span>] == L[-<span class="number">1</span>]:</span><br><span class="line"> L.popleft() <span class="comment"># Efficiently remove the first element (O(1) operation)</span></span><br><span class="line"> L.pop() <span class="comment"># Efficiently remove the last element (O(1) operation)</span></span><br><span class="line"> <span class="keyword">return</span> <span class="built_in">list</span>(L) <span class="comment"># Convert the deque back to a list and return it</span></span><br></pre></td></tr></table></figure><h1 id="Exercise-4"><a href="#Exercise-4" class="headerlink" title="Exercise 4:"></a>Exercise 4:</h1><p>This exercise deals with lists of integers that are in increasing order. The goal is to remove any element whose value is equal to its index in the list. The program iterates over the list and removes such elements, ensuring the index is correctly adjusted after each removal.</p><p>Key Points:</p><ul><li>The program uses a while loop and checks if the element at index <code>i</code> is equal to <code>i</code>. If true, it removes the element and does not increment i, so that the next element at the same position is checked.</li><li>The <code>remove()</code> function is used to delete the element, which is appropriate for this task.</li><li>Care is taken to ensure that index adjustments are handled correctly.</li></ul><p>The reason we use <code>remove()</code> instead of <code>pop(0)</code> or <code>popleft()</code> in a deque is that we need to specifically remove the value that matches the number we reached. <code>pop()</code> and <code>popleft()</code> remove elements by position, without considering the value, which isn’t suitable for our case.</p><h3 id="Standard-Solution-3"><a href="#Standard-Solution-3" class="headerlink" title="Standard Solution:"></a>Standard Solution:</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f4</span>(<span class="params">L</span>):</span><br><span class="line"> i = <span class="number">0</span></span><br><span class="line"> <span class="keyword">while</span> i < <span class="built_in">len</span>(L):</span><br><span class="line"> <span class="keyword">if</span> L[i] == i:</span><br><span class="line"> L.pop(i)</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> i += <span class="number">1</span></span><br><span class="line"> <span class="keyword">return</span> L</span><br></pre></td></tr></table></figure><h3 id="My-Solution-2"><a href="#My-Solution-2" class="headerlink" title="My Solution:"></a>My Solution:</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f4</span>(<span class="params">L</span>):</span><br><span class="line"> i = <span class="number">0</span></span><br><span class="line"> <span class="keyword">while</span> i < <span class="built_in">len</span>(L):</span><br><span class="line"> <span class="keyword">if</span> L[i] == i:</span><br><span class="line"> L.remove(L[i]) <span class="comment"># Using remove() here since popleft() removes from the left only</span></span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> i += <span class="number">1</span> <span class="comment"># Only increment i if no element was removed</span></span><br><span class="line"> <span class="keyword">return</span> L</span><br></pre></td></tr></table></figure><h1 id="Exercise-5"><a href="#Exercise-5" class="headerlink" title="Exercise 5:"></a>Exercise 5:</h1><p>This exercise works with a circular list of integers. The task is to identify elements that are both larger than one of their adjacent elements and smaller than the other. The result is returned as a dictionary where each key is such an element, and its value is a pair of the adjacent elements (one smaller and one larger).</p><p>Key Points:</p><ul><li>The list is treated as circular, meaning the first element is considered adjacent to the last element.</li><li>The program iterates through the list, compares each element with its neighbors, and stores those that meet the criteria.</li><li>For each valid element, the adjacent smaller and larger elements are stored in a dictionary.</li></ul><p>To solve this problem, we need to create a dictionary D where each key is an element in the list L that satisfies a certain condition, and the value is a tuple of two elements. The first element of this tuple is the adjacent element that is smaller than the current key, and the second element is the adjacent element that is larger than the current key.</p><p>Steps:</p><ol><li>Loop structure: Check each element.</li><li>Processing of adjacent elements: Since the list is cyclic, the previous element of the first element is the last element, and the next element of the last element is the first element.</li><li>Condition check: Find the adjacent elements that are smaller and larger than the current element, and add them to the result dictionary.</li></ol><h3 id="Standard-Solution-4"><a href="#Standard-Solution-4" class="headerlink" title="Standard Solution:"></a>Standard Solution:</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f5</span>(<span class="params">L</span>):</span><br><span class="line"> D = {}</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="built_in">len</span>(L)):</span><br><span class="line"> m = L[i - <span class="number">1</span>]</span><br><span class="line"> L[i]</span><br><span class="line"> <span class="comment"># Treat it as a head-tail circular array</span></span><br><span class="line"> n = L[(i + <span class="number">1</span>) % <span class="built_in">len</span>(L)]</span><br><span class="line"> <span class="comment"># we don't care about the order of m and n [0,1,2,4] L[3%4==3]</span></span><br><span class="line"> <span class="keyword">if</span> n < m:</span><br><span class="line"> m, n = n, m</span><br><span class="line"> <span class="comment"># If L[i] is between m and n, store it in the dictionary:</span></span><br><span class="line"> <span class="keyword">if</span> m < L[i] < n:</span><br><span class="line"> D[L[i]] = m, n</span><br><span class="line"> <span class="keyword">return</span> D</span><br></pre></td></tr></table></figure><p><code>L[i-1]</code> help us to get the previous element of the current element, <code>0</code> - <code>1</code> is <code>len(L) - 1</code>.<br>and <code>L[(i+1) % len(L)]</code> help us to get the next element of the current element. The modulo operation <code>(i+1) % len(L)</code> ensures that the index wraps around to the beginning of the list when it reaches the end. </p><h1 id="Exercise-6"><a href="#Exercise-6" class="headerlink" title="Exercise 6:"></a>Exercise 6:</h1><p>This exercise deals with factorizing an integer n into the form <code>2^k * m</code>, where <code>m</code> is an odd number. If <code>n</code> is negative, the program adds a negative sign to the output. If <code>n</code> is zero, it prints a special message.</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f6</span>(<span class="params">n</span>):</span><br><span class="line"> <span class="keyword">if</span> <span class="keyword">not</span> n:</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">'0 = 2^k * 0 for all integers k!'</span>)</span><br><span class="line"> <span class="keyword">return</span></span><br><span class="line"> k = <span class="number">0</span></span><br><span class="line"> m = n</span><br><span class="line"> sign = <span class="string">'-'</span> <span class="keyword">if</span> n < <span class="number">0</span> <span class="keyword">else</span> <span class="string">''</span></span><br><span class="line"> <span class="keyword">while</span> m % <span class="number">2</span> == <span class="number">0</span>:</span><br><span class="line"> m //= <span class="number">2</span></span><br><span class="line"> k += <span class="number">1</span></span><br><span class="line"> <span class="built_in">print</span>(<span class="string">f'<span class="subst">{n}</span> = <span class="subst">{sign}</span>2^<span class="subst">{k}</span> * <span class="subst">{<span class="built_in">abs</span>(m)}</span>'</span>)</span><br></pre></td></tr></table></figure><ul><li>If n is negative, it keeps track of the sign.</li><li>It repeatedly divides n by 2 while it remains even (n % 2 == 0), counting how many times this happens (k).</li><li>The remaining number, m, must be odd, because we divide out all possible factors of 2.</li><li>Finally, it prints the equation:<br><code>"n = sign * 2^k * m"</code></li></ul><p><strong>FOR VERY VERY VERY VERY VERY BIG NUMBER:</strong></p><p>When dealing with very large integers, the method of continuously dividing the number by 2 to factor out powers of 2 (2^k) can become inefficient. This is because each division can be costly in terms of computational time, especially for very large numbers with millions or billions of digits. Each division involves recalculating the entire integer, which is slow for large integers.<br>Using Bit Manipulation:</p><p>A much more efficient approach is to use <strong>bit manipulation</strong> to determine how many times a number can be divided by 2 (i.e., how many factors of 2 it has). This method avoids division altogether and instead directly analyzes the binary representation of the number to count the number of trailing zeros, which correspond to the powers of 2 in the factorization.</p><h3 id="Why"><a href="#Why" class="headerlink" title="Why?"></a>Why?</h3><ol><li><p>Bitwise operations are much faster than arithmetic operations like division, especially for large integers. Counting the trailing zeros in a number’s binary representation can be done in constant time.</p></li><li><p>Extracting the lowest set bit of a number allows us to quickly find how many times a number can be divided by 2 without having to repeatedly divide the number. This provides the power of 2 (k) directly.</p></li></ol><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f6</span>(<span class="params">n</span>):</span><br><span class="line"> <span class="keyword">if</span> n == <span class="number">0</span>:</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">"0 = 2^k * 0 for all integers k!"</span>)</span><br><span class="line"> <span class="keyword">return</span></span><br><span class="line"> </span><br><span class="line"> <span class="comment"># Handle negative sign</span></span><br><span class="line"> sign = <span class="string">'-'</span> <span class="keyword">if</span> n < <span class="number">0</span> <span class="keyword">else</span> <span class="string">''</span></span><br><span class="line"> n = <span class="built_in">abs</span>(n)</span><br><span class="line"> </span><br><span class="line"> <span class="comment"># Using bit manipulation to count how many trailing zeros (powers of 2)</span></span><br><span class="line"> k = (n & -n).bit_length() - <span class="number">1</span> <span class="comment"># Count trailing zeros by isolating the lowest set bit</span></span><br><span class="line"> </span><br><span class="line"> <span class="comment"># Remove 2^k factor from n</span></span><br><span class="line"> m = n >> k <span class="comment"># Equivalent to n // 2^k, shifting right by k bits</span></span><br><span class="line"> </span><br><span class="line"> <span class="comment"># Print the result</span></span><br><span class="line"> <span class="built_in">print</span>(<span class="string">f"<span class="subst">{sign}</span><span class="subst">{n}</span> = <span class="subst">{sign}</span>2^<span class="subst">{k}</span> * <span class="subst">{m}</span>"</span>)</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html"><h1 id="Exercise-1"><a href="#Exercise-1" class="headerlink" title="Exercise 1:"></a>Exercise 1:</h1><p>This exercise focuses on input valid</summary>
<category term="Python" scheme="https://longsizhuo.github.io/tags/Python/"/>
<category term="Answer" scheme="https://longsizhuo.github.io/tags/Answer/"/>
</entry>
<entry>
<title>Windows7+SSH</title>
<link href="https://longsizhuo.github.io/post/60f249e3.html"/>
<id>https://longsizhuo.github.io/post/60f249e3.html</id>
<published>2025-01-23T16:29:53.890Z</published>
<updated>2025-02-18T08:42:15.455Z</updated>
<content type="html"><![CDATA[<h3 id="How-to-solve-the-problem-of-UNPROTECTED-PRIVATE-KEY-FILE"><a href="#How-to-solve-the-problem-of-UNPROTECTED-PRIVATE-KEY-FILE" class="headerlink" title="How to solve the problem of UNPROTECTED PRIVATE KEY FILE?"></a>How to solve the problem of UNPROTECTED PRIVATE KEY FILE?</h3><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">F:\> ssh -i "id_rsa" -p 2251 ??@??.com</span><br><span class="line">@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@</span><br><span class="line">@ WARNING: UNPROTECTED PRIVATE KEY FILE! @</span><br><span class="line">@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@</span><br><span class="line">Permissions for 'id_rsa' are too open.</span><br><span class="line">It is required that your private key files are NOT accessible by others.</span><br><span class="line">This private key will be ignored.</span><br><span class="line">Load key "id_rsa": bad permissions</span><br><span class="line">??@??.com: Permission denied (publickey).</span><br></pre></td></tr></table></figure><p>So I went home and tested it with my old computer:</p><ol><li><p>An error message appeared: <code>ssh: The term 'ssh' is not recognized as the name of a cmdlet, function, script file, or operable program</code></p></li><li><p>Checked whether OpenSSH was installed through <code>Get-WindowsCapability -Online | ? Name -like 'OpenSSH*'</code>, and found that Windows7 system does not natively support OpenSSH</p></li><li><p>Tried to solve it by installing <code>Git Bash</code>, but <code>Unable to locate the program input point GetSystemTimePreciseAsFileTime on the dynamic link library KERNEL32.dll</code></p></li><li><p>Tried <code>Release</code> on the <code>OpenSSH</code> official website, and found that it could not be compiled because the <code>api-ms-win-core-file-l1-1-0.dll</code> file was missing in the computer</p></li><li><p><code>Cygwin</code> official website found that it supports <code>unsupported Windows version</code>, <a href="https://cygwin.com/install.html">https://cygwin.com/install.html</a></p></li><li><p><code>Win+R</code>-><code>cmd</code>-><code>setup-x86_64.exe --allow-unsupported-windows --site http://ctm.crouchingtigerhiddenfruitbat.org/pub/cygwin/circa/64bit/2024/01/30/231215 --no-verify</code></p></li><li><p>Successfully run Cygwin, set up the Tsinghua University mirror source, <a href="https://mirrors.tuna.tsinghua.edu.cn/cygwin/">https://mirrors.tuna.tsinghua.edu.cn/cygwin/</a>, select <code>openssh</code>, and install various C++ packages</p></li><li><p>It still failed, and then I found that the key file can be used after it is removed from the USB drive. . .</p></li></ol>]]></content>
<summary type="html"><h3 id="How-to-solve-the-problem-of-UNPROTECTED-PRIVATE-KEY-FILE"><a href="#How-to-solve-the-problem-of-UNPROTECTED-PRIVATE-KEY-FILE" class=</summary>
<category term="SSH" scheme="https://longsizhuo.github.io/tags/SSH/"/>
</entry>
<entry>
<title>Lattice</title>
<link href="https://longsizhuo.github.io/post/49e7fe92.html"/>
<id>https://longsizhuo.github.io/post/49e7fe92.html</id>
<published>2025-01-20T07:37:28.321Z</published>
<updated>2025-01-20T15:39:54.901Z</updated>
<content type="html"><![CDATA[<h1 id="Lattice-based-Cryptography-Basic-Example"><a href="#Lattice-based-Cryptography-Basic-Example" class="headerlink" title="Lattice-based Cryptography: Basic Example"></a>Lattice-based Cryptography: Basic Example</h1><h2 id="Introduction-to-Lattice"><a href="#Introduction-to-Lattice" class="headerlink" title="Introduction to Lattice"></a>Introduction to Lattice</h2><p>In lattice-based cryptography, a lattice is a regularly spaced grid of points in space. It is formed by taking integer linear combinations of a set of vectors, called the “basis”. For this example, let’s use a 2-dimensional lattice, where the lattice points are integer combinations of two vectors.</p><!-- tikzjax-placeholder-974720a88e01bdd202e8008eb1f0b545 --><h3 id="Why-Can-Bad-Basis-Be-Used-for-Encryption-and-Good-Basis-for-Decryption"><a href="#Why-Can-Bad-Basis-Be-Used-for-Encryption-and-Good-Basis-for-Decryption" class="headerlink" title="Why Can Bad Basis Be Used for Encryption, and Good Basis for Decryption?"></a>Why Can Bad Basis Be Used for Encryption, and Good Basis for Decryption?</h3><p>The core issue lies in lattice-based encryption, where information is mapped to a lattice, encrypted using the <strong>public key</strong> (Bad Basis), and finally decrypted using the <strong>private key</strong> (Good Basis). The key point here is the geometric properties of Good Basis and Bad Basis.</p><h4 id="Encryption-Process-Using-Bad-Basis-as-Public-Key"><a href="#Encryption-Process-Using-Bad-Basis-as-Public-Key" class="headerlink" title="Encryption Process (Using Bad Basis as Public Key):"></a>Encryption Process (Using Bad Basis as Public Key):</h4><p>In the encryption process, the dense lattice structure generated by <strong>Bad Basis</strong> maps the message to a lattice point.<br>Suppose we want to encrypt a message. First, we choose a random error (noise) and then add some randomness to the message so that the encrypted message can be represented as a point in the lattice. Since the lattice structure of <strong>Bad Basis</strong> is very dense and hard to manipulate, attackers cannot directly recover the original message from the encrypted one.</p><h4 id="Decryption-Process-Using-Good-Basis-as-Private-Key"><a href="#Decryption-Process-Using-Good-Basis-as-Private-Key" class="headerlink" title="Decryption Process (Using Good Basis as Private Key):"></a>Decryption Process (Using Good Basis as Private Key):</h4><p>During decryption, the <strong>private key</strong> uses <strong>Good Basis</strong>. Since the basis vectors of <strong>Good Basis</strong> are orthogonal, the lattice structure is clearer and easier to manipulate, making it possible to recover the information using <strong>Good Basis</strong>.<br>Specifically, using <strong>Good Basis</strong>, we can find the closest lattice point (i.e., recover the original message using the decryption formula). Because the lattice structure generated by <strong>Good Basis</strong> is simple, decryption becomes very easy.</p><h4 id="Why-Can-We-Use-Bad-Basis-for-Encryption-and-Good-Basis-for-Decryption"><a href="#Why-Can-We-Use-Bad-Basis-for-Encryption-and-Good-Basis-for-Decryption" class="headerlink" title="Why Can We Use Bad Basis for Encryption and Good Basis for Decryption?"></a>Why Can We Use Bad Basis for Encryption and Good Basis for Decryption?</h4><p>The key lies in the relationship between <strong>Bad Basis</strong> and <strong>Good Basis</strong>:</p><p><strong>Good Basis</strong> and <strong>Bad Basis</strong> are mathematically related, as they belong to the same lattice. Although the lattice structure generated by <strong>Bad Basis</strong> is more complex and dense, it is still a different representation of the lattice defined by <strong>Good Basis</strong>. Through mathematical operations, we can convert <strong>Bad Basis</strong> into <strong>Good Basis</strong> and recover information from it.</p><p>In fact, the relationship between <strong>Bad Basis</strong> and <strong>Good Basis</strong> can be obtained through matrix operations. Using specific algorithms, such as <strong>Babai’s rounding algorithm</strong>, we can use the information from <strong>Bad Basis</strong> to find the closest <strong>Good Basis</strong> point. Since the structure of <strong>Good Basis</strong> is clearer, it is easy to recover the original message using its basis vectors during decryption.</p><p>The security of lattice-based encryption relies on a mathematical problem: recovering the shortest vector (or the correct message) from a dense lattice (defined by <strong>Bad Basis</strong>) is a very difficult problem. This problem, known as the <strong>Shortest Vector Problem (SVP)</strong>, is currently not efficiently solvable by existing quantum algorithms.</p><hr><h3 id="Explanation-of-Key-Points"><a href="#Explanation-of-Key-Points" class="headerlink" title="Explanation of Key Points"></a><strong>Explanation of Key Points</strong></h3><ul><li><p><strong>Lattice Structure</strong>: The lattice is generated by linear combinations of basis vectors $( \mathbf{v_1} )$ and $( \mathbf{v_2} )$. In this example, the vectors are simple, but in real applications, the lattice structure is much more complex.</p></li><li><p><strong>Encryption</strong>: The message is transformed into a ciphertext through lattice operations, typically involving some noise or error terms (such as in LWE).</p></li><li><p><strong>Decryption</strong>: The secret key (a vector or some form of trapdoor information) is used to recover the original message by solving lattice-related problems.</p></li></ul><p>This Markdown example is a basic introduction, and in practical lattice-based schemes, the lattice vectors, encryption, and decryption processes are far more intricate. But this should provide a simple framework for understanding the key concepts.</p>]]></content>
<summary type="html"><h1 id="Lattice-based-Cryptography-Basic-Example"><a href="#Lattice-based-Cryptography-Basic-Example" class="headerlink" title="Lattice-base</summary>
</entry>
<entry>
<title>MyCalendar</title>
<link href="https://longsizhuo.github.io/post/9a3257a2.html"/>
<id>https://longsizhuo.github.io/post/9a3257a2.html</id>
<published>2025-01-20T07:37:28.171Z</published>
<updated>2025-01-20T07:37:28.171Z</updated>
<content type="html"><![CDATA[<h1 id="QUESTION:"><a href="#QUESTION:" class="headerlink" title="QUESTION:"></a>QUESTION:</h1><p><a href="https://leetcode.cn/problems/my-calendar-iii/submissions/591093593/?envType=daily-question&envId=2025-01-04">MyCalendar.md</a></p><h1 id="My-Think:"><a href="#My-Think:" class="headerlink" title="My Think:"></a>My Think:</h1><p>Today we are talking about MyCalendar I II III. The daily questions for these three days are the same, so we will do them together.</p><p>今天我们讲MyCalendar I II III, 这三天的每日一题都是一样的,所以一起做了.</p><h3 id="I"><a href="#I" class="headerlink" title="I:"></a>I:</h3><p>We use binary search to find where <code>startTime</code> can be inserted, and return <code>False</code> if it is found in advance. After finding the insertion point, we can check whether there is overlap.</p><p>我们用二分查找, 查找 <code>startTime</code> 在哪里可以插入, 如果提前找到了直接返回 <code>False</code>. 找到了插入点后, 再检查是否有重叠即可.</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">MyCalendar</span>:</span><br><span class="line"></span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self</span>):</span><br><span class="line"> <span class="variable language_">self</span>.date = []</span><br><span class="line"></span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">book</span>(<span class="params">self, startTime: <span class="built_in">int</span>, endTime: <span class="built_in">int</span></span>) -> <span class="built_in">bool</span>:</span><br><span class="line"> <span class="comment"># Binary Search 二分查找 </span></span><br><span class="line"> n = <span class="built_in">len</span>(<span class="variable language_">self</span>.date)</span><br><span class="line"> left, right = <span class="number">0</span>, n - <span class="number">1</span></span><br><span class="line"> <span class="keyword">while</span> left <= right:</span><br><span class="line"> mid = (left + right) // <span class="number">2</span></span><br><span class="line"> <span class="keyword">if</span> <span class="variable language_">self</span>.date[mid][<span class="number">0</span>] < startTime:</span><br><span class="line"> left = mid + <span class="number">1</span> <span class="comment"># Move the left pointer 移动左指针</span></span><br><span class="line"> <span class="keyword">elif</span> <span class="variable language_">self</span>.date[mid][<span class="number">0</span>] > startTime:</span><br><span class="line"> right = mid - <span class="number">1</span> <span class="comment"># Move the right pointer 移动右指针</span></span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">False</span> <span class="comment"># Find the overlap 发现重叠</span></span><br><span class="line"> <span class="comment"># Check for overlap with previous and next intervals 检查与前后区间的重叠</span></span><br><span class="line"> <span class="keyword">if</span> left > <span class="number">0</span> <span class="keyword">and</span> <span class="variable language_">self</span>.date[left - <span class="number">1</span>][<span class="number">1</span>] > startTime:</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">False</span></span><br><span class="line"> <span class="keyword">if</span> left < <span class="built_in">len</span>(<span class="variable language_">self</span>.date) <span class="keyword">and</span> <span class="variable language_">self</span>.date[left][<span class="number">0</span>] < endTime:</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">False</span></span><br><span class="line"></span><br><span class="line"> <span class="comment"># Insert it 插入区间</span></span><br><span class="line"> <span class="variable language_">self</span>.date.insert(left, (startTime, endTime))</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">True</span></span><br></pre></td></tr></table></figure><h3 id="II"><a href="#II" class="headerlink" title="II:"></a>II:</h3><p>This question requires us to check whether there will be three reservations under the conditions of the previous question. Although binary search can also be done, it will be much more complicated. We introduce the idea of differential (Line Sweep) in this question.</p><ol><li><p>Record the changes at each time point (start and end)<br>When a new interval <code>[startTime, endTime)</code> is to be inserted:</p><ol><li>At the position corresponding to <code>startTime</code> +1</li><li>At the position corresponding to <code>endTime</code> -1<br>In this way, we only record “how much the overlap number should be added/subtracted at these two boundary time points”.</li></ol></li><li><p>Count the current maximum overlap when necessary<br>Sort all-time points (keys) from small to large, and accumulate their +1/-1 values in turn.<br>The result of the accumulation is the number of activities carried out simultaneously at the corresponding time (that is, the “overlap number”).<br>If you want to find out whether there is a triple reservation, see whether the maximum of this accumulation process reaches 3 (or higher)</p></li></ol><p>这道题要求我们在上一道题的条件下, 检查是否会出现三次预定. 二分查找虽然也可以做, 但是会复杂很多. 我们在这一题引入差分(Line Sweep)的思想.</p><ol><li><p>记录每个时间点(开始与结束)的变化<br> 当有新的区间 <code>[startTime, endTime)</code> 要插入时:</p><ol><li>在 <code>startTime</code> 对应的位置 +1</li><li>在 <code>endTime</code> 对应的位置 -1<br>这样我们只记录“在这两个边界时间点,重叠数量要加/减多少”。</li></ol></li><li><p>在需要时统计当前的最大重叠<br>把所有的时间点(key)从小到大排序,依次累加其 +1/-1 值。<br>累加的结果就是对应时刻同时进行的活动数量(也就是“重叠数量”)。<br>如果要查找是否出现三重预定,就看这个累加过程最大是否到达 3(或更高)</p></li></ol><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> sortedcontainers <span class="keyword">import</span> SortedDict</span><br><span class="line"><span class="keyword">class</span> <span class="title class_">MyCalendarTwo</span>:</span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self</span>):</span><br><span class="line"> <span class="variable language_">self</span>.sd = SortedDict()</span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">book</span>(<span class="params">self, startTime: <span class="built_in">int</span>, endTime: <span class="built_in">int</span></span>) -> <span class="built_in">bool</span>:</span><br><span class="line"> <span class="variable language_">self</span>.sd[startTime] = <span class="variable language_">self</span>.sd.get(startTime, <span class="number">0</span>) + <span class="number">1</span></span><br><span class="line"> <span class="variable language_">self</span>.sd[endTime] = <span class="variable language_">self</span>.sd.get(endTime, <span class="number">0</span>) - <span class="number">1</span></span><br><span class="line"> s = <span class="number">0</span></span><br><span class="line"> <span class="keyword">for</span> v <span class="keyword">in</span> <span class="variable language_">self</span>.sd.values():</span><br><span class="line"> s += v</span><br><span class="line"> <span class="keyword">if</span> s > <span class="number">2</span>:</span><br><span class="line"> <span class="variable language_">self</span>.sd[startTime] -= <span class="number">1</span></span><br><span class="line"> <span class="variable language_">self</span>.sd[endTime] += <span class="number">1</span></span><br><span class="line"> <span class="keyword">return</span> <span class="literal">False</span></span><br><span class="line"> <span class="keyword">return</span> <span class="literal">True</span></span><br></pre></td></tr></table></figure><h3 id="III"><a href="#III" class="headerlink" title="III:"></a>III:</h3><p>This question is even more difficult. It requires us to find the maximum number of multiple reservations. We can just record it based on the previous question.</p><ol><li><p>Difference record</p><p> Same as before: <code>+1</code> at the position corresponding to <code>startTime</code>, <code>-1</code> at the position corresponding to <code>endTime</code>.</p><p> Store in <code>self.sd</code>: <code>key</code> = time point, <code>value</code> = increase or decrease at that time point.</p></li><li><p>Find the maximum number of overlaps</p><p> Use a rolling variable ongoing to indicate “how many overlaps there are at the current moment”.<br> Each time a time point is traversed, the corresponding difference is accumulated to ongoing, and then <code>max_overlap = max(max_overlap, ongoing)</code> is updated.</p></li></ol><p>这道题更加过分, 要求我们找到多重预定中最多有多少重, 我们就在上一道题的基础上记录即可.</p><ol><li><p>差分记录</p><p> 与之前一致:在 <code>startTime</code> 对应的位置 +<code>1</code>,在 <code>endTime</code> 对应的位置 <code>-1</code>。<br> <code>self.sd</code> 中存储:key=时间点, <code>value</code>=该时间点的增减量。</p></li><li><p>求最大重叠数</p><p> 用一个滚动变量 <code>ongoing</code> 表示“当前时刻有多少重叠”。<br> 每遍历一个时间点,把对应的差分累加到 <code>ongoing</code>,然后更新 <code>max_overlap = max(max_overlap, ongoing)</code>。</p></li></ol><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> sortedcontainers <span class="keyword">import</span> SortedDict</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">MyCalendarThree</span>:</span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self</span>):</span><br><span class="line"> <span class="variable language_">self</span>.sd = SortedDict()</span><br><span class="line"></span><br><span class="line"> <span class="variable language_">self</span>.max_overlap = <span class="number">0</span></span><br><span class="line"></span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">book</span>(<span class="params">self, startTime: <span class="built_in">int</span>, endTime: <span class="built_in">int</span></span>) -> <span class="built_in">int</span>:</span><br><span class="line"> <span class="comment"># First, record the "plus 1" and "minus 1" of this reservation.先把这次预定的“加1”和“减1”记录下来</span></span><br><span class="line"> <span class="variable language_">self</span>.sd[startTime] = <span class="variable language_">self</span>.sd.get(startTime, <span class="number">0</span>) + <span class="number">1</span></span><br><span class="line"> <span class="variable language_">self</span>.sd[endTime] = <span class="variable language_">self</span>.sd.get(endTime, <span class="number">0</span>) - <span class="number">1</span></span><br><span class="line"></span><br><span class="line"> <span class="comment"># Temporary variable, record the number of overlaps 临时变量, 记录几折叠</span></span><br><span class="line"> ongoing = <span class="number">0</span> <span class="comment"># Current overlap number</span></span><br><span class="line"> tmp_max = <span class="number">0</span></span><br><span class="line"> <span class="keyword">for</span> v <span class="keyword">in</span> <span class="variable language_">self</span>.sd.values():</span><br><span class="line"> ongoing += v</span><br><span class="line"> tmp_max = <span class="built_in">max</span>(ongoing, tmp_max)</span><br><span class="line"> <span class="variable language_">self</span>.max_overlap = <span class="built_in">max</span>(<span class="variable language_">self</span>.max_overlap, tmp_max)</span><br><span class="line"> <span class="keyword">return</span> <span class="variable language_">self</span>.max_overlap</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html"><h1 id="QUESTION:"><a href="#QUESTION:" class="headerlink" title="QUESTION:"></a>QUESTION:</h1><p><a href="https://leetcode.cn/problems/my-c</summary>
<category term="Python" scheme="https://longsizhuo.github.io/tags/Python/"/>
<category term="Answer" scheme="https://longsizhuo.github.io/tags/Answer/"/>
<category term="Prefix Sum" scheme="https://longsizhuo.github.io/tags/Prefix-Sum/"/>
<category term="Binary Search" scheme="https://longsizhuo.github.io/tags/Binary-Search/"/>
<category term="Design" scheme="https://longsizhuo.github.io/tags/Design/"/>
<category term="Segment Tree" scheme="https://longsizhuo.github.io/tags/Segment-Tree/"/>
<category term="Ordered Set" scheme="https://longsizhuo.github.io/tags/Ordered-Set/"/>
</entry>
<entry>
<title>2270. Number of Ways to Split Array</title>
<link href="https://longsizhuo.github.io/post/c25bb550.html"/>
<id>https://longsizhuo.github.io/post/c25bb550.html</id>
<published>2025-01-13T22:31:00.000Z</published>
<updated>2025-03-03T04:43:52.611Z</updated>
<content type="html"><![CDATA[<h1 id="QUESTION:"><a href="#QUESTION:" class="headerlink" title="QUESTION:"></a>QUESTION:</h1><p><a href="https://leetcode.cn/problems/number-of-ways-to-split-array/description/">2270. Number of Ways to Split Array.md</a></p><h1 id="My-Think:"><a href="#My-Think:" class="headerlink" title="My Think:"></a>My Think:</h1><p><code>2 <= nums.length <= 105</code>, 因此我们可以直接获取到第一个数字, 初始状态就在指针于index0, 正要往index1走的时候.<br>然后只需要一次For循环就可以搞定</p><p>重点是第二个方法, 来自题解.</p><h1 id="Code:"><a href="#Code:" class="headerlink" title="Code:"></a>Code:</h1><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Solution</span>:</span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">waysToSplitArray</span>(<span class="params">self, nums: <span class="type">List</span>[<span class="built_in">int</span>]</span>) -> <span class="built_in">int</span>:</span><br><span class="line"> temp_sum = nums[<span class="number">0</span>]</span><br><span class="line"> total_sum = <span class="built_in">sum</span>(nums) - temp_sum</span><br><span class="line"> ans = <span class="number">0</span></span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">1</span>, <span class="built_in">len</span>(nums)):</span><br><span class="line"> <span class="keyword">if</span> temp_sum >= total_sum:</span><br><span class="line"> ans += <span class="number">1</span></span><br><span class="line"> temp_sum += nums[i]</span><br><span class="line"> total_sum -= nums[i]</span><br><span class="line"> <span class="keyword">return</span> ans</span><br></pre></td></tr></table></figure><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">t = (<span class="built_in">sum</span>(nums) + <span class="number">1</span>) // <span class="number">2</span></span><br><span class="line"><span class="keyword">return</span> <span class="built_in">sum</span>(s >= t <span class="keyword">for</span> s <span class="keyword">in</span> accumulate(nums[:-<span class="number">1</span>]))</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html"><h1 id="QUESTION:"><a href="#QUESTION:" class="headerlink" title="QUESTION:"></a>QUESTION:</h1><p><a href="https://leetcode.cn/problems/numb</summary>
<category term="Python" scheme="https://longsizhuo.github.io/tags/Python/"/>
<category term="Answer" scheme="https://longsizhuo.github.io/tags/Answer/"/>
</entry>
<entry>
<title>post-gu</title>
<link href="https://longsizhuo.github.io/post/c87ff78a.html"/>
<id>https://longsizhuo.github.io/post/c87ff78a.html</id>
<published>2025-01-08T13:14:00.000Z</published>
<updated>2025-03-03T04:38:11.604Z</updated>
<content type="html"><![CDATA[<h1 id="Notes-on-RSA-and-Diffie-Hellman"><a href="#Notes-on-RSA-and-Diffie-Hellman" class="headerlink" title="Notes on RSA and Diffie-Hellman"></a>Notes on RSA and Diffie-Hellman</h1><h2 id="1-Mathematical-Background-of-RSA-and-Diffie-Hellman"><a href="#1-Mathematical-Background-of-RSA-and-Diffie-Hellman" class="headerlink" title="1. Mathematical Background of RSA and Diffie-Hellman"></a>1. Mathematical Background of RSA and Diffie-Hellman</h2><h3 id="RSA"><a href="#RSA" class="headerlink" title="RSA"></a>RSA</h3><ul><li><strong>Prime Factorization</strong>: The problem of integer factorization.</li><li><strong>Diffie-Hellman</strong>: The discrete logarithm problem.</li></ul><p>Let:</p><p>$$<br>s \in \mathbb{Z}_n^2, a_i \in \mathbb{Z}_2^n, e_i \in \mathbb{Z}^n<br>$$</p><p>Define:</p><p>$$<br>a_i \cdot s + e_i<br>$$</p><p>as a certain encryption form.</p><p>For example:</p><p>$$<br>\mathbb{Z}_n^2 = {7, 11, 13, 15, 17, 19, 23, 27, 31}<br>$$</p><hr><h3 id="2-RSA-Algorithm-Steps"><a href="#2-RSA-Algorithm-Steps" class="headerlink" title="2. RSA Algorithm Steps"></a>2. RSA Algorithm Steps</h3><ol><li><p><strong>Choose two prime numbers:</strong></p><p>$$<br>p = 3, q = 11<br>$$</p><p>Then:</p><p>$$<br>n = p \cdot q = 3 \cdot 11 = 33<br>$$</p><p>$$<br>\phi(n) = (p-1)(q-1) = 2 \cdot 10 = 20<br>$$</p><p>(Computing the number of integers coprime to ( n ))</p><ul><li>Since ( p, q ) are primes, for all ( a \in \mathbb{Z}^+ ), if ( a < p ), then ( \gcd(a, p) = 1 ), where ( p ) is a prime.</li><li>There are ( (p-1) ) and ( (q-1) ) numbers coprime to ( pq ).</li><li>The total count of numbers up to ( n ) is ( n = p \cdot q ), and ( n ) is divisible by ( q ) and ( p ).</li><li>The total count of numbers not coprime to ( n ) is ( p + q - 1 ).</li><li>Therefore, ( \phi(n) = n - (q + p - 1) = pq - q - p + 1 = (p-1)(q-1) ).</li></ul></li><li><p><strong>Choose a public key ( e ):</strong></p><p>$$<br>1 < e < \phi(n), , \text{and} , \gcd(e, \phi(n)) = 1<br>$$</p><p>For example:</p><p>$$<br>e = 7<br>$$</p></li><li><p><strong>Compute the private key ( d ):</strong></p><p>$$<br>d \cdot e \equiv 1 , (\text{mod} , \phi(n))<br>$$</p><p>Solving:</p><p>$$<br>d = 3<br>$$</p></li><li><p><strong>Public-private key pair:</strong></p><ul><li>Public key: ( (e, n) = (7, 33) )</li><li>Private key: ( (d, n) = (3, 33) )</li></ul></li></ol><hr><h3 id="3-Encryption-and-Decryption-Process"><a href="#3-Encryption-and-Decryption-Process" class="headerlink" title="3. Encryption and Decryption Process"></a>3. Encryption and Decryption Process</h3><ul><li><p>Suppose the plaintext is ( m = 4 ), the ciphertext ( c ) is:</p><p>$$<br>c = m^e , \text{mod} , n<br>$$</p><p>Calculation:</p><p>$$<br>c = 4^7 , \text{mod} , 33 = 16<br>$$</p></li><li><p>Decrypting to retrieve ( m ):</p><p>$$<br>m = c^d , \text{mod} , n<br>$$</p><p>Calculation:</p><p>$$<br>m = 16^3 , \text{mod} , 33 = 4<br>$$</p></li></ul><hr><h3 id="4-Proof-of-Correctness-of-Decryption"><a href="#4-Proof-of-Correctness-of-Decryption" class="headerlink" title="4. Proof of Correctness of Decryption"></a>4. Proof of Correctness of Decryption</h3><p>The encryption and decryption rely on the following equation:</p><p>$$<br>e \cdot d \equiv 1 ,(\text{mod}, \phi(n))<br>$$</p><p>Thus, we have:</p><p>$$<br>e \cdot d = 1 + k \cdot \phi(n)<br>$$</p><ol><li><p>From the encryption formula:</p><p>$$<br>c = m^e ,(\text{mod}, n)<br>$$</p></li><li><p>Using the decryption formula:</p><p>$$<br>m = c^d ,(\text{mod}, n)<br>$$</p></li><li><p>Substituting ( c ) from the encryption equation:</p><p>$$<br>m = (m^e)^d ,(\text{mod}, n)<br>$$</p></li><li><p>Consolidating the exponent:</p><p>$$<br>m = m^{e \cdot d} ,(\text{mod}, n)<br>$$</p></li><li><p>Since ( e \cdot d = 1 + k \cdot \phi(n) ):</p><p>$$<br>m = m^{1 + k \cdot \phi(n)} ,(\text{mod}, n)<br>$$</p></li><li><p>Applying Euler’s theorem:</p><p>$$<br>m^{\phi(n)} \equiv 1 ,(\text{mod}, n)<br>$$</p></li><li><p>Simplifying:</p><p>$$<br>m^{1 + k \cdot \phi(n)} \equiv m^1 \cdot (m^{\phi(n)})^k ,(\text{mod}, n)<br>$$</p></li><li><p>Since ( m^{\phi(n)} \equiv 1 ):</p><p>$$<br>m^{1 + k \cdot \phi(n)} \equiv m ,(\text{mod}, n)<br>$$</p></li></ol><p>Thus, decryption is correct.</p><hr><p>LWD:<br>$$<br>\left{ \left(a_i, \langle a_i, s \rangle + e_i \right) : s \gets \mathbb{Z}_q^n, a_i \gets \mathbb{Z}<em>q^n, e_i \gets \chi \right}</em>{i=1}^m<br>$$</p><ol><li>( \mathbb{Z} = \mathbb{Z}/q \mathbb{Z} ) represents a finite ring modulo ( q ).</li><li>( \chi ) is a probability distribution over ( \mathbb{Z} ), used to generate “small numbers” (noise).</li></ol><ul><li><strong>Uniform Distribution</strong>: ( \chi ) randomly generates integer values from the range [<strong>−B</strong>, <strong>B</strong>] (e.g., [−5,5]), where ( B \ll q/2 ).<br>The assumption ( B \ll q/2 ) ensures that the noise ( e_i ) does not obscure the modulated result during decryption.</li><li><strong>Discrete Gaussian Distribution</strong>: Another common distribution, denoted as ( D_{\mathbb{Z}, \sigma} ), with standard deviation ( \sigma ), used to generate near-zero random noise values.</li></ul><p>( a \gets D ): <strong>a</strong> is randomly sampled (or generated) from probability distribution <strong>D</strong>.<br>( a \gets S ): When <strong>S</strong> is a finite set, <strong>a</strong> is randomly and uniformly selected from <strong>S</strong>.</p><p>( a_i \in \mathbb{Z}_q^n ): This denotes an ( n )-dimensional vector space modulo ( q ), where each component belongs to ( \mathbb{Z}_q ).</p>]]></content>
<summary type="html"><h1 id="Notes-on-RSA-and-Diffie-Hellman"><a href="#Notes-on-RSA-and-Diffie-Hellman" class="headerlink" title="Notes on RSA and Diffie-Hellma</summary>
<category term="Python" scheme="https://longsizhuo.github.io/tags/Python/"/>
<category term="Answerhe" scheme="https://longsizhuo.github.io/tags/Answerhe/"/>
</entry>
<entry>
<title>2241. Design an ATM Machine</title>
<link href="https://longsizhuo.github.io/post/a21411f.html"/>
<id>https://longsizhuo.github.io/post/a21411f.html</id>
<published>2025-01-06T00:00:00.000Z</published>
<updated>2025-01-20T07:37:28.170Z</updated>
<content type="html"><![CDATA[<h1 id="QUESTION:"><a href="#QUESTION:" class="headerlink" title="QUESTION:"></a>QUESTION:</h1><p><a href="https://leetcode.cn/problems/design-an-atm-machine/description/?envType=daily-question&envId=2025-01-05">2241. Design an ATM Machine.md</a><br>There is an ATM machine that stores banknotes of 5 denominations: 20, 50, 100, 200, and 500 dollars. Initially the ATM is empty. The user can use the machine to deposit or withdraw any amount of money.</p><p>When withdrawing, the machine prioritizes using banknotes of larger values.</p><p>For example, if you want to withdraw $300 and there are 2 $50 banknotes, 1 $100 banknote, and 1 $200 banknote, then the machine will use the $100 and $200 banknotes.<br>However, if you try to withdraw $600 and there are 3 $200 banknotes and 1 $500 banknote, then the withdraw request will be rejected because the machine will first try to use the $500 banknote and then be unable to use banknotes to complete the remaining $100. Note that the machine is not allowed to use the $200 banknotes instead of the $500 banknote.<br>Implement the ATM class:</p><p>ATM() Initializes the ATM object.<br>void deposit(int[] banknotesCount) Deposits new banknotes in the order $20, $50, $100, $200, and $500.<br>int[] withdraw(int amount) Returns an array of length 5 of the number of banknotes that will be handed to the user in the order $20, $50, $100, $200, and $500, and update the number of banknotes in the ATM after withdrawing. Returns [-1] if it is not possible (do not withdraw any banknotes in this case).</p><h1 id="My-Think:"><a href="#My-Think:" class="headerlink" title="My Think:"></a>My Think:</h1><p>The purpose of this question is to simulate an ATM machine, which returns the amount of money you withdraw, no more and no less. I am greedy, because the second sentence “There are 3 <code>$200</code> bills and 1 <code>$500</code> bill in the machine, so the withdrawal request will be rejected”<br>This shows that we can skip thinking about the knapsack problem in complex dynamic programming and directly consider simple greed.</p><p>Because the denominations of the deposited money are only <code>20</code>, <code>50</code>, <code>100</code>, <code>200</code>, <code>500</code>, we can store them in the list in advance and wait for traversal.</p><p>Then we create a <code>defaultdict()</code> to create a hash table for each denomination in the ATM machine.</p><p><code>deposit()</code> creates a reverse traversal dictionary. Because we need to traverse the dictionary from large denominations to small denominations, the reverse dictionary is very convenient at this time.</p><p>Assuming the initial <code>amount</code> is <code>600</code>, the first denomination traversed is <code>500</code>, It fits the logic of the question very well</p><p>For the <code>withdraw()</code> function, I created a temporary dictionary deep copy storage so that the initial array will not be changed when <code>[-1]</code> is returned. Otherwise, it will be troublesome to backtrack.</p><p>Here, Sylvia and I used two different traversal methods. She traversed the list of denominations, while I traversed the dictionary directly (actually traversed the key directly).</p><ol><li><p>If the current denomination (<code>600</code>) is greater than the current denomination (<code>500</code>), then try to deduct it. If the bank money is withdrawn directly, then look at the next denomination.</p></li><li><p>If it is not withdrawn, then <code>amount</code> deducts the deductible share and then continues to look at the next denomination.</p></li><li><p>If there is still <code>amount</code> left at the end, return <code>[-1]</code>, otherwise calculate how many bills have been consumed in total, which is the answer.</p></li></ol><p>这道题的目的是模拟一台ATM机器, 让你取多少钱, 就返回多少钱, 不能多也不能少. 我是贪心的思想, 因为第二句”机器里有 3 张 <code>$200</code> 的钞票和1 张 <code>$500</code> 的钞票,那么取款请求会被拒绝”<br>这就说明我们可以跳过思考复杂的动态规划中的背包问题, 而直接考虑简单的贪心.</p><p>因为存的钱的面额只有<code>20</code>, <code>50</code>, <code>100</code>, <code>200</code>, <code>500</code> 这五种面额, 于是我们提前存在列表里面等待遍历即可.<br>然后我们创建一个<code>defaultdict()</code>, 为ATM机器里面的每种面额创建哈希表.</p><p><code>deposit()</code>创建了一个反向遍历的字典. 因为我们需要从大面额到小面额遍历字典, 在这个时候反向的字典就很方便.</p><pre><code>假设初始`amount`为`600`, 遍历到的第一个面额就是`500`, 就很符合题目的逻辑</code></pre><p><code>withdraw()</code>函数, 我之所以创建了一个临时字典深拷贝储存是在返回<code>[-1]</code>的情况下不更改初始数组. 否则还要回溯挺麻烦的.</p><p>这里我和Sylvia用了两种不同的遍历方式, 她遍历了面额的列表, 而我是直接遍历的字典(实际上直接遍历的key).</p><ol><li>如果当前面额(<code>600</code>)大于了当前面额(<code>500</code>), 那就尝试扣除, 如果直接把银行钱取完了, 那再看下一个面值.</li><li>如果没有取完, 那么<code>amount</code>扣除掉能扣除的份额, 再继续看下一个面额即可.</li><li>到最后<code>amount</code>还有剩余则返回<code>[-1]</code>, 否则计算一共消耗了多少张钞票, 即是答案了.</li></ol><h1 id="Code:"><a href="#Code:" class="headerlink" title="Code:"></a>Code:</h1><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> copy</span><br><span class="line"><span class="keyword">from</span> typing <span class="keyword">import</span> <span class="type">List</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">from</span> collections <span class="keyword">import</span> defaultdict</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">ATM</span>:</span><br><span class="line"></span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self</span>):</span><br><span class="line"> <span class="variable language_">self</span>.sd = defaultdict(<span class="built_in">int</span>)</span><br><span class="line"> <span class="variable language_">self</span>.amount = [<span class="string">'20'</span>, <span class="string">'50'</span>, <span class="string">'100'</span>, <span class="string">'200'</span>, <span class="string">'500'</span>]</span><br><span class="line"></span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">deposit</span>(<span class="params">self, banknotesCount: <span class="type">List</span>[<span class="built_in">int</span>]</span>) -> <span class="literal">None</span>:</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="built_in">len</span>(banknotesCount) - <span class="number">1</span>, -<span class="number">1</span>, -<span class="number">1</span>):</span><br><span class="line"> <span class="variable language_">self</span>.sd[<span class="variable language_">self</span>.amount[i]] += banknotesCount[i]</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">withdraw</span>(<span class="params">self, amount: <span class="built_in">int</span></span>) -> <span class="type">List</span>[<span class="built_in">int</span>]:</span><br><span class="line"> tempSd = copy.deepcopy(<span class="variable language_">self</span>.sd)</span><br><span class="line"> <span class="comment"># key = 面值, value = 张数</span></span><br><span class="line"> <span class="keyword">for</span> key, value <span class="keyword">in</span> tempSd.items():</span><br><span class="line"> <span class="keyword">if</span> amount >= <span class="built_in">int</span>(key) <span class="keyword">and</span> value > <span class="number">0</span>:</span><br><span class="line"> <span class="comment"># 需要多少张钞票</span></span><br><span class="line"> howManyPiece = amount // <span class="built_in">int</span>(key)</span><br><span class="line"> <span class="keyword">if</span> howManyPiece >= value:</span><br><span class="line"> <span class="comment"># 全部取出来</span></span><br><span class="line"> tempSd[key] = <span class="number">0</span></span><br><span class="line"> amount -= value * <span class="built_in">int</span>(key)</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> <span class="comment"># 取出这么多钞票</span></span><br><span class="line"> tempSd[key] -= howManyPiece</span><br><span class="line"> amount -= <span class="built_in">int</span>(key) * howManyPiece</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> <span class="keyword">if</span> amount > <span class="number">0</span>:</span><br><span class="line"> <span class="keyword">return</span> [-<span class="number">1</span>]</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> ans = []</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="variable language_">self</span>.sd.keys():</span><br><span class="line"> ans.append(<span class="variable language_">self</span>.sd[i] - tempSd[i])</span><br><span class="line"> <span class="variable language_">self</span>.sd = copy.deepcopy(tempSd)</span><br><span class="line"> <span class="keyword">return</span> ans[::-<span class="number">1</span>]</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html"><h1 id="QUESTION:"><a href="#QUESTION:" class="headerlink" title="QUESTION:"></a>QUESTION:</h1><p><a href="https://leetcode.cn/problems/desi</summary>
<category term="Python" scheme="https://longsizhuo.github.io/tags/Python/"/>
<category term="Answer" scheme="https://longsizhuo.github.io/tags/Answer/"/>
</entry>
<entry>
<title>3046. Split the Array</title>
<link href="https://longsizhuo.github.io/post/41577de2.html"/>
<id>https://longsizhuo.github.io/post/41577de2.html</id>
<published>2024-12-30T10:23:08.034Z</published>
<updated>2024-12-30T10:23:08.040Z</updated>
<content type="html"><![CDATA[<h1 id="Description"><a href="#Description" class="headerlink" title="Description:"></a>Description:</h1><p>You are given an integer array nums of even length. You have to split the array into two parts nums1 and nums2 such that:</p><p>nums1.length == nums2.length == nums.length / 2.<br>nums1 should contain distinct elements.<br>nums2 should also contain distinct elements.<br>Return true if it is possible to split the array, and false otherwise.</p><p>Example 1:</p><p>Input: nums = [1,1,2,2,3,4]<br>Output: true<br>Explanation: One of the possible ways to split nums is nums1 = [1,2,3] and nums2 = [1,2,4].<br>Example 2:</p><p>Input: nums = [1,1,1,1]<br>Output: false<br>Explanation: The only possible way to split nums is nums1 = [1,1] and nums2 = [1,1]. Both nums1 and nums2 do not contain distinct elements. Therefore, we return false.</p><h1 id="Thinking"><a href="#Thinking" class="headerlink" title="Thinking:"></a>Thinking:</h1><p>题目要求判断是否可以将数组分成两个部分,使得两个部分的元素都是不同的。<br>最开始考虑的是<code>Counter()</code>记录每个数字是否满足某个条件,如果不满足就返回<code>False</code>。后面发现不需要<code>Counter</code>,普通的字典记录,中途遇到某个数字大于2就返回False即可。</p><h1 id="Code"><a href="#Code" class="headerlink" title="Code:"></a>Code:</h1><figure class="highlight python"><figcaption><span>O(2n)</span></figcaption><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Solution</span>:</span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">isPossibleToSplit</span>(<span class="params">self, nums: <span class="type">List</span>[<span class="built_in">int</span>]</span>) -> <span class="built_in">bool</span>:</span><br><span class="line"> Counter_nums = Counter(nums)</span><br><span class="line"> <span class="keyword">for</span> i, j <span class="keyword">in</span> Counter_nums.items():</span><br><span class="line"> <span class="keyword">if</span> j > <span class="number">2</span>:</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">False</span></span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">True</span></span><br></pre></td></tr></table></figure><figure class="highlight python"><figcaption><span>O(n)</span></figcaption><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Solution</span>:</span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">isPossibleToSplit</span>(<span class="params">self, nums: <span class="type">List</span>[<span class="built_in">int</span>]</span>) -> <span class="built_in">bool</span>:</span><br><span class="line"> count = {}</span><br><span class="line"> <span class="keyword">for</span> num <span class="keyword">in</span> nums:</span><br><span class="line"> count[num] = count.get(num, <span class="number">0</span>) + <span class="number">1</span></span><br><span class="line"> <span class="keyword">if</span> count[num] > <span class="number">2</span>:</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">False</span></span><br><span class="line"> <span class="keyword">return</span> <span class="literal">True</span></span><br></pre></td></tr></table></figure>]]></content>
<summary type="html"><h1 id="Description"><a href="#Description" class="headerlink" title="Description:"></a>Description:</h1><p>You are given an integer array n</summary>
</entry>
<entry>
<title>3138. Minimum Length of Anagram Concatenation</title>
<link href="https://longsizhuo.github.io/post/d1339d55.html"/>
<id>https://longsizhuo.github.io/post/d1339d55.html</id>
<published>2024-12-30T10:23:08.032Z</published>
<updated>2024-12-30T10:23:08.038Z</updated>
<content type="html"><![CDATA[<h1 id="Description"><a href="#Description" class="headerlink" title="Description:"></a>Description:</h1><p><a href="https://leetcode.cn/problems/minimum-length-of-anagram-concatenation/description/?envType=daily-question&envId=2024-12-20">https://leetcode.cn/problems/minimum-length-of-anagram-concatenation/description/?envType=daily-question&envId=2024-12-20</a><br>You are given a string <code>s</code>, which is known to be a concatenation of anagrams of some string <code>t</code>.</p><p>Return the minimum possible length of the string <code>t</code>.</p><p>An anagram is formed by rearranging the letters of a string. For example, “aab”, “aba”, and, “baa” are anagrams of “aab”.</p><h4 id="Example-1"><a href="#Example-1" class="headerlink" title="Example 1:"></a>Example 1:</h4><pre><code>Input: s = "abba"Output: 2Explanation:One possible string t could be "ba".</code></pre><h4 id="Example-2"><a href="#Example-2" class="headerlink" title="Example 2:"></a>Example 2:</h4><pre><code>Input: s = "cdef"Output: 4Explanation:One possible string t could be "cdef", notice that t can be equal to s.</code></pre><h1 id="Thinking"><a href="#Thinking" class="headerlink" title="Thinking:"></a>Thinking:</h1><p>Since the problem naturally suggests using a counting method (<code>Counter</code>), we need to find the minimum substring for each string. For example, for <code>abba</code>, the result is <code>ab</code>; for <code>cdef</code>, it’s <code>cdef</code>.<br>We iterate from length <code>1</code> (a single character) onwards, slicing the string to get the current substring.</p><p>Initially, we compute the character count for the original string using <code>Counter</code>, which gives us a dictionary of character frequencies.<br>Next, we only need to check if the count of each character in the current substring multiplied by <code>n/k</code> equals the count in the original string (i.e., whether repeating the current substring x times equals the original string).</p><p>由于题意很容易联想到这道题要进行计数(Counter). 我们需要找到每个字符串的最小子串,<code>abba</code>为<code>ab</code>, <code>cdef</code>为<code>cdef</code>. 于是我们从长度0(即单个字符)开始遍历,期间通过切片的形式来获取当前子串。<br>因为最开始我们对原始字符串进行了Counter,得到了字符数量和字符对应的字典。接下来我们只需要判断当前子串的Counter到的某个字符的数值乘以<code>n/k</code>是否等于原始字符串的Counter的值即可(即当前子串乘以x倍是否等于源字符串)。</p><h1 id="Code"><a href="#Code" class="headerlink" title="Code:"></a>Code:</h1><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> collections</span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Solution</span>:</span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">minAnagramLength</span>(<span class="params">self, s: <span class="built_in">str</span></span>) -> <span class="built_in">int</span>:</span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">check</span>(<span class="params">k: <span class="built_in">int</span></span>) -> <span class="built_in">bool</span>:</span><br><span class="line"> <span class="comment"># 遍历字符串 s,每次取长度为 k 的子串</span></span><br><span class="line"> <span class="comment"># Iterate over the string `s`, taking substrings of length `k`</span></span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, n, k):</span><br><span class="line"> <span class="comment"># 统计每个字符出现的次数</span></span><br><span class="line"> <span class="comment"># Count the occurrences of each character in the current substring</span></span><br><span class="line"> cnt1 = collections.Counter(s[i: i + k])</span><br><span class="line"> <span class="keyword">for</span> c, v <span class="keyword">in</span> cnt.items():</span><br><span class="line"> <span class="comment"># 如果每个字符出现的次数乘以 n/k != cnt[] return False</span></span><br><span class="line"> <span class="comment"># If the count of any character multiplied by (n // k) != the original count, return False</span></span><br><span class="line"> <span class="keyword">if</span> cnt1[c] * (n // k) != v:</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">False</span></span><br><span class="line"> <span class="keyword">return</span> <span class="literal">True</span></span><br><span class="line"></span><br><span class="line"> cnt = collections.Counter(s)</span><br><span class="line"> n = <span class="built_in">len</span>(s)</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">1</span>, n+<span class="number">1</span>):</span><br><span class="line"> <span class="keyword">if</span> n % i == <span class="number">0</span> <span class="keyword">and</span> check(i):</span><br><span class="line"> <span class="keyword">return</span> i</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html"><h1 id="Description"><a href="#Description" class="headerlink" title="Description:"></a>Description:</h1><p><a href="https://leetcode.cn/pro</summary>
<category term="Python" scheme="https://longsizhuo.github.io/tags/Python/"/>
<category term="Hash Table" scheme="https://longsizhuo.github.io/tags/Hash-Table/"/>
<category term="String" scheme="https://longsizhuo.github.io/tags/String/"/>
<category term="Counting" scheme="https://longsizhuo.github.io/tags/Counting/"/>
<category term="Prefix Sum" scheme="https://longsizhuo.github.io/tags/Prefix-Sum/"/>
</entry>
<entry>
<title>1366. Rank Teams by Votes</title>
<link href="https://longsizhuo.github.io/post/3ab349b3.html"/>
<id>https://longsizhuo.github.io/post/3ab349b3.html</id>
<published>2024-12-30T10:23:07.791Z</published>
<updated>2024-12-30T10:23:07.791Z</updated>
<content type="html"><![CDATA[<h1 id="QUESTION:"><a href="#QUESTION:" class="headerlink" title="QUESTION:"></a>QUESTION:</h1><p><a href="https://leetcode.cn/problems/rank-teams-by-votes/description/?envType=daily-question&envId=2024-12-29">1366. Rank Teams by Votes.md</a><br>In a special ranking system, each voter gives a rank from highest to lowest to all teams participating in the competition.</p><p>The ordering of teams is decided by who received the most position-one votes. If two or more teams tie in the first position, we consider the second position to resolve the conflict, if they tie again, we continue this process until the ties are resolved. If two or more teams are still tied after considering all positions, we rank them alphabetically based on their team letter.</p><p>You are given an array of strings votes which is the votes of all voters in the ranking systems. Sort all teams according to the ranking system described above.</p><p>Return a string of all teams sorted by the ranking system.</p><p>Example 1:</p><p>Input: votes = [“ABC”,”ACB”,”ABC”,”ACB”,”ACB”]<br>Output: “ACB”<br>Explanation:<br>Team A was ranked first place by 5 voters. No other team was voted as first place, so team A is the first team.<br>Team B was ranked second by 2 voters and ranked third by 3 voters.<br>Team C was ranked second by 3 voters and ranked third by 2 voters.<br>As most of the voters ranked C second, team C is the second team, and team B is the third.<br>Example 2:</p><p>Input: votes = [“WXYZ”,”XYZW”]<br>Output: “XWYZ”<br>Explanation:<br>X is the winner due to the tie-breaking rule. X has the same votes as W for the first position, but X has one vote in the second position, while W does not have any votes in the second position.<br>Example 3:</p><p>Input: votes = [“ZMNAGUEDSJYLBOPHRQICWFXTVK”]<br>Output: “ZMNAGUEDSJYLBOPHRQICWFXTVK”<br>Explanation: Only one voter, so their votes are used for the ranking.</p><p>Constraints:</p><p>1 <= votes.length <= 1000<br>1 <= votes[i].length <= 26<br>votes[i].length == votes[j].length for 0 <= i, j < votes.length.<br>votes[i][j] is an English uppercase letter.<br>All characters of votes[i] are unique.<br>All the characters that occur in votes[0] also occur in votes[j] where 1 <= j < votes.length.</p><h1 id="My-Think:"><a href="#My-Think:" class="headerlink" title="My Think:"></a>My Think:</h1><p>This question requires us to count their votes. The first thing that comes to mind is to build a double structure, similar to this:<br>这道题要求我们统计他们的投票情况. 首先想到的就是构建一个双重结构体, 类似于这样:</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">type <span class="class"><span class="keyword">struct</span> {</span></span><br><span class="line"> <span class="type">char</span> A {</span><br><span class="line"> <span class="number">1</span>: <span class="number">1</span>;</span><br><span class="line"> <span class="number">2</span>: <span class="number">1</span>;</span><br><span class="line"> <span class="number">3</span>: <span class="number">1</span>;</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>Then fill in the dictionary in a double loop and sort it. It’s very simple in Python, but I thought it was complicated at first and built the sorting logic manually.<br>Finally, we can use lambda expression <code>sorted_teams = sorted(rank.keys(), key = lambda x: ([-rank[x][i] for i in range(len(votes[0]))], x))</code></p><p>What needs to be noted in Go is the usage of the standard answer. Use <code>slices.SortedFunc</code> to sort the teams. The sorting rules are defined according to the requirements of the question:</p><ol><li>Sort in descending order by votes.</li><li>If the votes are the same, sort in ascending alphabetical order.<br><code>maps.Keys(cnts)</code> gets the keys of all teams (that is, the characters of all teams)<br><code>slices.Compare(cnts[b], cnts[a])</code>: compare the vote slices of two teams and sort in descending order by votes (<code>b</code> comes first).<br><code>cmp.Compare(a, b)</code>: when the votes are the same, sort in ascending alphabetical order.<br><code>cmp.Or</code>: execute the first comparison rule. If the return value is not 0 (that is, there is a priority difference), return directly; otherwise execute the next rule.</li></ol><p>然后在一个双重循环中填写这个字典, 最后进行排序即可. 在Python中十分简单, 但是我一开始想复杂了, 手动构建了排序逻辑.<br>最后用lambda表达式即可<code>sorted_teams = sorted(rank.keys(), key = lambda x: ([-rank[x][i] for i in range(len(votes[0]))], x))</code></p><p>Go里需要注意的是标准答案的用法, 使用 <code>slices.SortedFunc</code> 对团队进行排序,排序规则按题目要求定义:</p><ol><li>按票数降序排列。</li><li>如果票数相同,按字母升序排列。<br><code>maps.Keys(cnts)</code> 获取所有团队的键(即所有团队的字符)<br><code>slices.Compare(cnts[b], cnts[a])</code>:比较两个团队的票数切片,按票数降序排列(<code>b</code> 在前)。<br><code>cmp.Compare(a, b)</code>:当票数相同时,按字母升序排列。<br><code>cmp.Or</code>:执行第一个比较规则,如果返回值非 0(即有优先级差异),直接返回;否则执行下一个规则。</li></ol><h1 id="Code:"><a href="#Code:" class="headerlink" title="Code:"></a>Code:</h1><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Solution</span>:</span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">rankTeams</span>(<span class="params">self, votes: <span class="type">List</span>[<span class="built_in">str</span>]</span>) -> <span class="built_in">str</span>:</span><br><span class="line"> rank = defaultdict(<span class="keyword">lambda</span>: defaultdict(<span class="built_in">int</span>))</span><br><span class="line"> <span class="keyword">for</span> value <span class="keyword">in</span> votes:</span><br><span class="line"> <span class="keyword">for</span> ind, c <span class="keyword">in</span> <span class="built_in">enumerate</span>(value):</span><br><span class="line"> rank[c][ind] += <span class="number">1</span></span><br><span class="line"> sorted_teams = <span class="built_in">sorted</span>(rank.keys(), key = <span class="keyword">lambda</span> x: ([-rank[x][i] <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="built_in">len</span>(votes[<span class="number">0</span>]))], x))</span><br><span class="line"> <span class="keyword">return</span> <span class="string">''</span>.join(sorted_teams)</span><br></pre></td></tr></table></figure><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">rankTeams_Siz</span>(<span class="params">self, votes: <span class="type">List</span>[<span class="built_in">str</span>]</span>) -> <span class="built_in">str</span>:</span><br><span class="line"> rank = defaultdict(<span class="keyword">lambda</span>: defaultdict(<span class="built_in">int</span>))</span><br><span class="line"> <span class="keyword">for</span> value <span class="keyword">in</span> votes:</span><br><span class="line"> <span class="keyword">for</span> ind, c <span class="keyword">in</span> <span class="built_in">enumerate</span>(value):</span><br><span class="line"> rank[c][ind] += <span class="number">1</span></span><br><span class="line"> <span class="built_in">print</span>(rank)</span><br><span class="line"> ans = <span class="string">''</span></span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="built_in">len</span>(votes[<span class="number">0</span>])):</span><br><span class="line"> temp_ans = <span class="string">''</span></span><br><span class="line"> count = <span class="number">0</span></span><br><span class="line"> <span class="keyword">for</span> key, value <span class="keyword">in</span> rank.items():</span><br><span class="line"> <span class="keyword">if</span> value[i] > count:</span><br><span class="line"> temp_ans = key</span><br><span class="line"> count = value[i]</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> <span class="comment"># 如果并列, 则考虑下一位 If there is a tie, consider the next one</span></span><br><span class="line"> <span class="keyword">while</span> value[i] == count:</span><br><span class="line"> i += <span class="number">1</span> <span class="comment"># 这个i是临时变量, 直接用 This i is a temporary variable, use it directly</span></span><br><span class="line"> <span class="keyword">if</span> i > <span class="built_in">len</span>(votes[<span class="number">0</span>]): <span class="comment"># 考虑找到最后都没找到的情况Consider the situation where you find nothing in the end.</span></span><br><span class="line"> <span class="comment"># 答案值应该是字母顺序 The answer values should be in alphabetical order</span></span><br><span class="line"> temp_ans = key</span><br><span class="line"> <span class="keyword">break</span></span><br><span class="line"> <span class="keyword">if</span> value[i] > count:</span><br><span class="line"> temp_ans = key</span><br><span class="line"> count = value[i]</span><br><span class="line"> ans += temp_ans</span><br><span class="line"> <span class="keyword">return</span> ans</span><br></pre></td></tr></table></figure><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">rankTeams</span><span class="params">(votes []<span class="type">string</span>)</span></span> <span class="type">string</span> {</span><br><span class="line"> cnts:=<span class="keyword">map</span>[<span class="type">rune</span>][]<span class="type">int</span>{}</span><br><span class="line"> <span class="keyword">for</span> _,ch := <span class="keyword">range</span> votes[<span class="number">0</span>] {</span><br><span class="line"> cnts[ch]=<span class="built_in">make</span>([]<span class="type">int</span>,<span class="built_in">len</span>(votes[<span class="number">0</span>]))</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">for</span> _,vote := <span class="keyword">range</span> votes{</span><br><span class="line"> <span class="keyword">for</span> i,ch := <span class="keyword">range</span> vote{</span><br><span class="line"> cnts[ch][i]++</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> res := slices.SortedFunc(maps.Keys(cnts),<span class="function"><span class="keyword">func</span><span class="params">(a,b <span class="type">rune</span>)</span></span> <span class="type">int</span>{</span><br><span class="line"> <span class="keyword">return</span> cmp.Or(slices.Compare(cnts[b],cnts[a]),cmp.Compare(a,b))</span><br><span class="line"> })</span><br><span class="line"> <span class="keyword">return</span> <span class="type">string</span>(res)</span><br><span class="line">}</span><br></pre></td></tr></table></figure><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> main</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> <span class="string">"sort"</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">rankTeams</span><span class="params">(votes []<span class="type">string</span>)</span></span> <span class="type">string</span> {</span><br><span class="line">rank := <span class="built_in">make</span>(<span class="keyword">map</span>[<span class="type">byte</span>]<span class="keyword">map</span>[<span class="type">int</span>]<span class="type">int</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> _, vote := <span class="keyword">range</span> votes {</span><br><span class="line"><span class="keyword">for</span> i := <span class="number">0</span>; i < <span class="built_in">len</span>(vote); i++ {</span><br><span class="line">team := vote[i]</span><br><span class="line"><span class="keyword">if</span> _, ok := rank[team]; !ok {</span><br><span class="line">rank[team] = <span class="built_in">make</span>(<span class="keyword">map</span>[<span class="type">int</span>]<span class="type">int</span>)</span><br><span class="line">}</span><br><span class="line">rank[team][i]++</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">teams := <span class="built_in">make</span>([]<span class="type">byte</span>, <span class="number">0</span>, <span class="built_in">len</span>(rank))</span><br><span class="line"><span class="keyword">for</span> team := <span class="keyword">range</span> rank {</span><br><span class="line">teams = <span class="built_in">append</span>(teams, team)</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">sort.Slice(teams, <span class="function"><span class="keyword">func</span><span class="params">(i, j <span class="type">int</span>)</span></span> <span class="type">bool</span> {</span><br><span class="line">a, b := teams[i], teams[j]</span><br><span class="line"><span class="keyword">for</span> k := <span class="number">0</span>; k < <span class="built_in">len</span>(votes[<span class="number">0</span>]); k++ {</span><br><span class="line"><span class="comment">// 比较两队在 k 排位的票数 // Compare the votes of the two teams in position k</span></span><br><span class="line">countA, countB := rank[a][k], rank[b][k]</span><br><span class="line"><span class="keyword">if</span> countA != countB {</span><br><span class="line"><span class="keyword">return</span> countA > countB <span class="comment">// 按票数降序 Sort by votes in descending order</span></span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line"><span class="keyword">return</span> a < b <span class="comment">// 字母升序 Alphabetical ascending</span></span><br><span class="line">})</span><br><span class="line"><span class="comment">// 拼接结果</span></span><br><span class="line"><span class="keyword">return</span> <span class="type">string</span>(teams)</span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html"><h1 id="QUESTION:"><a href="#QUESTION:" class="headerlink" title="QUESTION:"></a>QUESTION:</h1><p><a href="https://leetcode.cn/problems/rank</summary>
<category term="Python" scheme="https://longsizhuo.github.io/tags/Python/"/>
<category term="Answer" scheme="https://longsizhuo.github.io/tags/Answer/"/>
<category term="Array" scheme="https://longsizhuo.github.io/tags/Array/"/>
<category term="Hash Table" scheme="https://longsizhuo.github.io/tags/Hash-Table/"/>
<category term="String" scheme="https://longsizhuo.github.io/tags/String/"/>
<category term="Counting" scheme="https://longsizhuo.github.io/tags/Counting/"/>
<category term="Sorting" scheme="https://longsizhuo.github.io/tags/Sorting/"/>
</entry>
<entry>
<title>3159. Find Occurrences of an Element in an Array</title>
<link href="https://longsizhuo.github.io/post/aec413e2.html"/>
<id>https://longsizhuo.github.io/post/aec413e2.html</id>
<published>2024-12-28T08:22:07.811Z</published>
<updated>2024-12-28T08:22:07.811Z</updated>
<content type="html"><![CDATA[<h1 id="QUESTION:"><a href="#QUESTION:" class="headerlink" title="QUESTION:"></a>QUESTION:</h1><p><a href="https://leetcode.cn/problems/find-occurrences-of-an-element-in-an-array/description/?envType=daily-question&envId=2024-12-27">3159. Find Occurrences of an Element in an Array.md</a><br>You are given an integer array nums, an integer array queries, and an integer x.</p><p>For each queries[i], you need to find the index of the queries[i]th occurrence of x in the nums array. If there are fewer than queries[i] occurrences of x, the answer should be -1 for that query.</p><p>Return an integer array answer containing the answers to all queries.</p><p>Example 1:</p><p>Input: nums = [1,3,1,7], queries = [1,3,2,4], x = 1</p><p>Output: [0,-1,2,-1]</p><p>Explanation:</p><p>For the 1st query, the first occurrence of 1 is at index 0.<br>For the 2nd query, there are only two occurrences of 1 in nums, so the answer is -1.<br>For the 3rd query, the second occurrence of 1 is at index 2.<br>For the 4th query, there are only two occurrences of 1 in nums, so the answer is -1.<br>Example 2:</p><p>Input: nums = [1,2,3], queries = [10], x = 5</p><p>Output: [-1]</p><p>Explanation:</p><p>For the 1st query, 5 doesn’t exist in nums, so the answer is -1.</p><p>Constraints:</p><p>1 <= nums.length, queries.length <= 105<br>1 <= queries[i] <= 105<br>1 <= nums[i], x <= 104</p><h1 id="My-Think:"><a href="#My-Think:" class="headerlink" title="My Think:"></a>My Think:</h1><p>I haven’t written a solution for a long time. Now that I’m on vacation, I’m starting over. This question requires us to find “all x’s indices” from the given nums, and then return the index address of the queries-th x.<br>So we can use the list generation formula <code>indices = [i for i, value in enumerate(nums) if value == x]</code> to return a list containing all x’s indices,<br>and then query them one by one.<br>First mistake: I didn’t consider the case where indices is empty, so <code>indices[q-1] out of range</code>.<br>Second mistake: I forgot that the for loop in Golang needs two parameters to receive the value passed by range.</p><p>很久没有写题解了,现在放假了于是重新开始了. 这一道题要求我们从给定的nums中找到”所有x的索引”, 然后返回第queries个x的索引地址即可.<br>于是我们可以用列表生成式<code>indices = [i for i, value in enumerate(nums) if value == x]</code>来返回一个包含所有x索引的列表,<br>然后依次在其中查询即可.<br>第一次错误: 没有考虑indices为空的情况, 于是<code>indices[q-1] out of range</code>.<br>第二次错误: 忘记了Golang里的for循环需要两个参数接收range传来的value.</p><h1 id="Code:"><a href="#Code:" class="headerlink" title="Code:"></a>Code:</h1><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Solution</span>:</span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">occurrencesOfElement</span>(<span class="params">self, nums: <span class="type">List</span>[<span class="built_in">int</span>], queries: <span class="type">List</span>[<span class="built_in">int</span>], x: <span class="built_in">int</span></span>) -> <span class="type">List</span>[<span class="built_in">int</span>]:</span><br><span class="line"> <span class="comment"># Find the indices of all elements equal to x</span></span><br><span class="line"> indices = [i <span class="keyword">for</span> i, value <span class="keyword">in</span> <span class="built_in">enumerate</span>(nums) <span class="keyword">if</span> value == x]</span><br><span class="line"> <span class="comment"># print(indices)</span></span><br><span class="line"> n = <span class="built_in">len</span>(indices)</span><br><span class="line"> ans = []</span><br><span class="line"> <span class="keyword">for</span> q <span class="keyword">in</span> queries:</span><br><span class="line"> <span class="keyword">if</span> indices <span class="keyword">and</span> q-<span class="number">1</span> < n:</span><br><span class="line"> ans.append(indices[q-<span class="number">1</span>])</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> ans.append(-<span class="number">1</span>)</span><br><span class="line"> <span class="keyword">return</span> ans</span><br></pre></td></tr></table></figure><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">occurrencesOfElement</span><span class="params">(nums []<span class="type">int</span>, queries []<span class="type">int</span>, x <span class="type">int</span>)</span></span> []<span class="type">int</span> {</span><br><span class="line"> <span class="keyword">var</span> indices []<span class="type">int</span></span><br><span class="line"> <span class="keyword">for</span> i, value := <span class="keyword">range</span> nums {</span><br><span class="line"> <span class="keyword">if</span> value == x {</span><br><span class="line"> indices = <span class="built_in">append</span>(indices, i)</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">var</span> ans []<span class="type">int</span></span><br><span class="line"> n := <span class="built_in">len</span>(indices)</span><br><span class="line"> <span class="keyword">for</span> _, q := <span class="keyword">range</span> queries { <span class="comment">// "_, q"</span></span><br><span class="line"> <span class="keyword">if</span> n > <span class="number">0</span> && q<span class="number">-1</span> < n { </span><br><span class="line"> ans = <span class="built_in">append</span>(ans, indices[q<span class="number">-1</span>])</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> ans = <span class="built_in">append</span>(ans, <span class="number">-1</span>)</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> ans</span><br><span class="line">}</span><br><span class="line"></span><br></pre></td></tr></table></figure>]]></content>
<summary type="html"><h1 id="QUESTION:"><a href="#QUESTION:" class="headerlink" title="QUESTION:"></a>QUESTION:</h1><p><a href="https://leetcode.cn/problems/find</summary>
<category term="Python" scheme="https://longsizhuo.github.io/tags/Python/"/>
<category term="Answer" scheme="https://longsizhuo.github.io/tags/Answer/"/>
<category term="Array" scheme="https://longsizhuo.github.io/tags/Array/"/>
<category term="Hash Table" scheme="https://longsizhuo.github.io/tags/Hash-Table/"/>
</entry>
<entry>
<title>9021_TUT_7</title>
<link href="https://longsizhuo.github.io/post/891330b3.html"/>
<id>https://longsizhuo.github.io/post/891330b3.html</id>
<published>2024-11-11T05:54:50.386Z</published>
<updated>2024-11-11T05:54:50.387Z</updated>
<content type="html"><![CDATA[<h1 id="Exercise-1"><a href="#Exercise-1" class="headerlink" title="Exercise 1"></a>Exercise 1</h1><h3 id="what-is-yield-in-python"><a href="#what-is-yield-in-python" class="headerlink" title="what is yield in python?"></a>what is <code>yield</code> in python?</h3><p>The yield keyword in Python is used to create generator functions. A generator function is a special kind of function that returns a generator iterator, which can be used to iterate over a sequence of values. Unlike a regular function that returns a single value using the return statement, a generator function can yield multiple values, one at a time, pausing its state between each one.</p><h3 id="How-it-works"><a href="#How-it-works" class="headerlink" title="How it works?"></a>How it works?</h3><p>When a generator function is called, it doesn’t execute its code immediately. Instead, it returns a generator object that can be iterated over. Each time you request the next item from the generator (using next() or a loop), the generator function resumes execution from where it last left off, runs until it hits a yield statement, and yields the value to the caller.</p><h3 id="Problem-Description"><a href="#Problem-Description" class="headerlink" title="Problem Description"></a>Problem Description</h3><p>First, we need to understand the requirements of the problem:</p><p>Input: A list of integers L, such as [n1, n2, n3, …]. Output:</p><ul><li>Output n1 lines of rank 1 X, which means X without indentation.</li><li>Between each pair of rank 1 X, output n2 lines of rank 2 X, which are indented with one tab (\t).</li><li>Between each pair of rank 2 X, output n3 lines of rank 3 X, which are indented with two tabs.</li><li>Continue this pattern until all elements in the list L have been processed.</li></ul><h3 id="My-solution"><a href="#My-solution" class="headerlink" title="My solution"></a>My solution</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f1</span>():</span><br><span class="line"> <span class="keyword">while</span> <span class="literal">True</span>:</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">" /\\"</span>)</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">"/ \\"</span>)</span><br><span class="line"> <span class="keyword">yield</span></span><br><span class="line"> <span class="built_in">print</span>(<span class="string">"----"</span>)</span><br><span class="line"> <span class="keyword">yield</span></span><br><span class="line"> <span class="built_in">print</span>(<span class="string">"\\ /"</span>)</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">" \\/"</span>)</span><br><span class="line"> <span class="keyword">yield</span></span><br><span class="line"> <span class="built_in">print</span>(<span class="string">" ||"</span>)</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">" ||"</span>)</span><br><span class="line"> <span class="keyword">yield</span></span><br></pre></td></tr></table></figure><h3 id="Standard-solution"><a href="#Standard-solution" class="headerlink" title="Standard solution"></a>Standard solution</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f1</span>():</span><br><span class="line"> <span class="keyword">while</span> <span class="literal">True</span>:</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">' /\\\n/ \\'</span>)</span><br><span class="line"> <span class="keyword">yield</span></span><br><span class="line"> <span class="built_in">print</span>(<span class="string">'----'</span>)</span><br><span class="line"> <span class="keyword">yield</span></span><br><span class="line"> <span class="built_in">print</span>(<span class="string">'\\ /\n \\/'</span>)</span><br><span class="line"> <span class="keyword">yield</span></span><br><span class="line"> <span class="built_in">print</span>(<span class="string">' ||\n ||'</span>)</span><br><span class="line"> <span class="keyword">yield</span></span><br></pre></td></tr></table></figure><h1 id="Exercise-2"><a href="#Exercise-2" class="headerlink" title="Exercise 2"></a>Exercise 2</h1><h3 id="Problem-Description-1"><a href="#Problem-Description-1" class="headerlink" title="Problem Description"></a>Problem Description</h3><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">Line: [1, 3, 3, 1]</span><br><span class="line"> | | |</span><br><span class="line"> i=0 i=1 i=2</span><br><span class="line"> ↓ ↓ ↓</span><br><span class="line">Calculate:1+3 3+3 3+1</span><br><span class="line"> ↓ ↓ ↓</span><br><span class="line">Results: 4 6 4</span><br></pre></td></tr></table></figure><h3 id="My-solution-1"><a href="#My-solution-1" class="headerlink" title="My solution"></a>My solution</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f2</span>():</span><br><span class="line"> <span class="comment"># initialized</span></span><br><span class="line"> row = [<span class="number">1</span>]</span><br><span class="line"> <span class="keyword">while</span> <span class="literal">True</span>:</span><br><span class="line"> <span class="keyword">yield</span> row</span><br><span class="line"> <span class="comment"># row[i] + row[i + 1] is the expression in list comprehension</span></span><br><span class="line"> row = [<span class="number">1</span>] + [row[i] + row[i + <span class="number">1</span>] <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="built_in">len</span>(row)-<span class="number">1</span>)] + [<span class="number">1</span>]</span><br></pre></td></tr></table></figure><h3 id="Standard-solution-1"><a href="#Standard-solution-1" class="headerlink" title="Standard solution"></a>Standard solution</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f2</span>():</span><br><span class="line"> L = [<span class="number">1</span>]</span><br><span class="line"> <span class="keyword">yield</span> L</span><br><span class="line"> <span class="keyword">while</span> <span class="literal">True</span>:</span><br><span class="line"> L = [<span class="number">1</span>] + [L[i] + L[i + <span class="number">1</span>] <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="built_in">len</span>(L) - <span class="number">1</span>)] + [<span class="number">1</span>]</span><br><span class="line"> <span class="keyword">yield</span> L</span><br></pre></td></tr></table></figure><h1 id="Exercise-3"><a href="#Exercise-3" class="headerlink" title="Exercise 3"></a>Exercise 3</h1><h3 id="Problem-Description-2"><a href="#Problem-Description-2" class="headerlink" title="Problem Description"></a>Problem Description</h3><p>First, we need to understand the requirements of the problem:</p><p>Input: A list of integers L, such as [n1, n2, n3, …]. Output:</p><ul><li>Output n1 lines of <strong>rank 1</strong> X, which means X without indentation.</li><li>Between each pair of <strong>rank 1</strong> X, output n2 lines of <strong>rank 2</strong> X, which are indented with one tab (\t).</li><li>Between each pair of <strong>rank 2</strong> X, output n3 lines of <strong>rank 3</strong> X, which are indented with two tabs.</li><li>Continue this pattern until all elements in the list L have been processed.</li></ul><h3 id="My-solution-2"><a href="#My-solution-2" class="headerlink" title="My solution"></a>My solution</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f3</span>(<span class="params">L</span>):</span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">helper</span>(<span class="params">L, rank</span>):</span><br><span class="line"> <span class="keyword">if</span> <span class="keyword">not</span> L:</span><br><span class="line"> <span class="keyword">return</span></span><br><span class="line"> n = L[<span class="number">0</span>]</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(n):</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">'\t'</span> * rank + <span class="string">'X'</span>)</span><br><span class="line"> <span class="keyword">if</span> i < n - <span class="number">1</span>:</span><br><span class="line"> helper(L[<span class="number">1</span>:], rank + <span class="number">1</span>)</span><br><span class="line"> helper(L, <span class="number">0</span>)</span><br></pre></td></tr></table></figure><p>We need to write a recursive function to handle this nested structure. Here is the implementation idea:</p><p>Define a helper function <code>helper(L, rank)</code>, where:</p><ul><li><code>L</code> is the list currently being processed.</li><li><code>rank</code> is the current level (indentation level).</li></ul><p>In the <code>helper</code> function:</p><ol><li>If the list is empty, return directly.</li><li>Get the number of lines to output at the current level, <code>n = L[0]</code>.</li><li>Use a loop to output <code>n</code> lines of the current level’s X, with each line having the corresponding number of tab characters (<code>\t</code>) based on the <code>rank</code>.</li><li>After each output, if it is not the last element and it is not the last line, recursively call <code>helper</code> to handle the next level of <code>X</code> lines.</li></ol><h3 id="Standard-solution-2"><a href="#Standard-solution-2" class="headerlink" title="Standard solution"></a>Standard solution</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">f3</span>(<span class="params">L</span>):</span><br><span class="line"> _f3(L, <span class="number">0</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">_f3</span>(<span class="params">L, n</span>):</span><br><span class="line"> <span class="keyword">if</span> n == <span class="built_in">len</span>(L):</span><br><span class="line"> <span class="keyword">return</span></span><br><span class="line"> <span class="keyword">for</span> _ <span class="keyword">in</span> <span class="built_in">range</span>(L[n] - <span class="number">1</span>):</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">'\t'</span> * n, <span class="string">'X'</span>, sep=<span class="string">''</span>)</span><br><span class="line"> _f3(L, n + <span class="number">1</span>)</span><br><span class="line"> <span class="keyword">if</span> L[n]:</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">'\t'</span> * n, <span class="string">'X'</span>, sep=<span class="string">''</span>)</span><br></pre></td></tr></table></figure><h1 id="Exercise-4"><a href="#Exercise-4" class="headerlink" title="Exercise 4"></a>Exercise 4</h1><h3 id="Problem-Description-3"><a href="#Problem-Description-3" class="headerlink" title="Problem Description"></a>Problem Description</h3><p><strong>Objective:</strong> Given a list <code>L</code> of integers, we need to:</p><ul><li>Break it down into sublists of <strong>equal length</strong>, where the <strong>length is maximal</strong>.</li><li>This process is <strong>recursive</strong>: each sublist is further broken down in the same manner.</li><li>The original list should be <strong>preserved</strong> (i.e., not modified).</li></ul><p><strong>Key Points:</strong></p><ul><li>We aim to split the list into the largest possible sublists of equal length (greater than 1) that evenly divide the length of the list.</li><li>The recursion continues until a sublist cannot be broken down further (i.e., its length cannot be divided into equal parts greater than 1).</li></ul><h3 id="My-solution-3"><a href="#My-solution-3" class="headerlink" title="My solution"></a>My solution</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> math <span class="keyword">import</span> sqrt</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">f4</span>(<span class="params">L</span>):</span><br><span class="line"> n = <span class="built_in">len</span>(L)</span><br><span class="line"> <span class="comment"># Try to find the maximal sublist length greater than 1</span></span><br><span class="line"> <span class="keyword">for</span> sublist_length <span class="keyword">in</span> <span class="built_in">range</span>(n // <span class="number">2</span>, <span class="number">1</span>, -<span class="number">1</span>):</span><br><span class="line"> <span class="keyword">if</span> n % sublist_length == <span class="number">0</span>:</span><br><span class="line"> <span class="comment"># Split the list into sublists</span></span><br><span class="line"> sublists = [f4(L[i:i + sublist_length]) <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, n, sublist_length)]</span><br><span class="line"> <span class="keyword">return</span> sublists</span><br><span class="line"> <span class="keyword">return</span> L.copy()</span><br></pre></td></tr></table></figure><h3 id="Standard-solution-3"><a href="#Standard-solution-3" class="headerlink" title="Standard solution"></a>Standard solution</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">f4</span>(<span class="params">L</span>):</span><br><span class="line"> <span class="keyword">for</span> n <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">2</span>, <span class="built_in">round</span>(sqrt(<span class="built_in">len</span>(L))) + <span class="number">1</span>):</span><br><span class="line"> <span class="keyword">if</span> <span class="built_in">len</span>(L) % n == <span class="number">0</span>:</span><br><span class="line"> w = <span class="built_in">len</span>(L) // n</span><br><span class="line"> <span class="keyword">return</span> [f4(L[i : i + w]) <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, <span class="built_in">len</span>(L), w)]</span><br><span class="line"> <span class="keyword">return</span> <span class="built_in">list</span>(L)</span><br></pre></td></tr></table></figure><h1 id="Exercise-5"><a href="#Exercise-5" class="headerlink" title="Exercise 5"></a>Exercise 5</h1><h3 id="Problem-Description-4"><a href="#Problem-Description-4" class="headerlink" title="Problem Description"></a>Problem Description</h3><p><strong>Objective</strong>: Given a special list <code>L</code> (a list whose elements are integers or other special lists), we need to return a dictionary where:</p><p>Keys are tuples of indices <code>(i_1, i_2, ..., i_n)</code>.<br>Values are integers <code>e</code>.<br>The keys represent the path of indices to reach an integer <code>e</code> within the nested list structure.</p><p><strong>Interpretation</strong>:</p><ul><li>If the key is <code>(i_1,)</code>, then <code>L[i_1]</code> is an integer <code>e</code>.</li><li>If the key is <code>(i_1, i_2)</code>, then <code>L[i_1][i_2]</code> is an integer <code>e</code>.</li><li>If the key is <code>(i_1, i_2, i_3)</code>, then <code>L[i_1][i_2][i_3]</code> is an integer <code>e</code>.</li><li>And so on.</li></ul><p><strong>Constraints:</strong></p><p>We need to handle any depth of nesting.<br>Use <code>isinstance()</code> to check if an element is an integer or a list.<br>The original list should not be modified.</p><h3 id="My-solution-4"><a href="#My-solution-4" class="headerlink" title="My solution"></a>My solution</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f5</span>(<span class="params">L</span>):</span><br><span class="line"> result = {}</span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">helper</span>(<span class="params">sublist, path</span>):</span><br><span class="line"> <span class="keyword">for</span> index, element <span class="keyword">in</span> <span class="built_in">enumerate</span>(sublist):</span><br><span class="line"> current_path = path + (index,)</span><br><span class="line"> <span class="keyword">if</span> <span class="built_in">isinstance</span>(element, <span class="built_in">int</span>):</span><br><span class="line"> result[current_path] = element</span><br><span class="line"> <span class="keyword">elif</span> <span class="built_in">isinstance</span>(element, <span class="built_in">list</span>):</span><br><span class="line"> helper(element, current_path)</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> <span class="comment"># If there are other types, you might want to handle them or raise an error</span></span><br><span class="line"> <span class="keyword">pass</span></span><br><span class="line"> helper(L, ())</span><br><span class="line"> <span class="keyword">return</span> result</span><br></pre></td></tr></table></figure><h3 id="Standard-solution-4"><a href="#Standard-solution-4" class="headerlink" title="Standard solution"></a>Standard solution</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f5</span>(<span class="params">L</span>):</span><br><span class="line"> D = {}</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="built_in">len</span>(L)):</span><br><span class="line"> <span class="keyword">if</span> <span class="built_in">isinstance</span>(L[i], <span class="built_in">int</span>):</span><br><span class="line"> D[(i,)] = L[i]</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> E = f5(L[i])</span><br><span class="line"> <span class="keyword">for</span> s <span class="keyword">in</span> E:</span><br><span class="line"> D[i, *s] = E[s]</span><br><span class="line"> <span class="keyword">return</span> D</span><br></pre></td></tr></table></figure><h3 id="Difference-between-my-solution-and-the-standard-solution"><a href="#Difference-between-my-solution-and-the-standard-solution" class="headerlink" title="Difference between my solution and the standard solution"></a>Difference between my solution and the standard solution</h3><p><strong>My Solution</strong></p><ul><li>Uses a Helper Function (helper): Your solution defines an inner function helper(sublist, path) to handle the recursion.</li><li>Explicit Path Passing: The path variable, representing the current position in the nested list, is explicitly passed and updated at each recursive call.</li><li>State Encapsulation: By using a nested function, the state (path and result) is encapsulated within the f5 function’s scope.<br><strong>Standard Solution</strong></li><li>Direct Recursion: The standard solution directly calls f5(L[i]) recursively without using a helper function.</li><li>Implicit Path Construction: It constructs the path by combining the current index i with the indices from the recursive call (s) using tuple unpacking.</li><li>Dictionary Merging: After each recursive call, it merges the returned dictionary E into the current dictionary D.</li></ul><h1 id="Exercise-6"><a href="#Exercise-6" class="headerlink" title="Exercise 6"></a>Exercise 6</h1><h3 id="Problem-Description-5"><a href="#Problem-Description-5" class="headerlink" title="Problem Description"></a>Problem Description</h3><p>The given problem is not strictly about the Fibonacci sequence, but it generalizes similar principles to a broader set of recursive relationships. In the problem, you’re asked to compute the n-th term of a series, where the series is defined by some initial terms (first_terms) and a set of recurrence factors (factors). The Fibonacci sequence is a special case of such a recurrence relation, where each term is the sum of the two preceding terms.</p><h3 id="My-solution-Wrong"><a href="#My-solution-Wrong" class="headerlink" title="My solution(Wrong)"></a>My solution(Wrong)</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">f6</span>(<span class="params">first_terms, factors, n</span>):</span><br><span class="line"> k = <span class="built_in">len</span>(first_terms) - <span class="number">1</span></span><br><span class="line"> sequence = first_terms.copy()</span><br><span class="line"> </span><br><span class="line"> <span class="comment"># If n is within the initial terms, return it directly</span></span><br><span class="line"> <span class="keyword">if</span> n <= k:</span><br><span class="line"> <span class="keyword">return</span> sequence[n]</span><br><span class="line"> </span><br><span class="line"> <span class="comment"># Compute terms iteratively up to n</span></span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(k + <span class="number">1</span>, n + <span class="number">1</span>):</span><br><span class="line"> xi = <span class="number">0</span></span><br><span class="line"> <span class="keyword">for</span> s <span class="keyword">in</span> <span class="built_in">range</span>(k + <span class="number">1</span>):</span><br><span class="line"> xi += factors[s] * sequence[i - k - <span class="number">1</span> + s]</span><br><span class="line"> sequence.append(xi)</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">return</span> sequence[n]</span><br></pre></td></tr></table></figure><h3 id="Standard-solution-5"><a href="#Standard-solution-5" class="headerlink" title="Standard solution"></a>Standard solution</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">f6</span>(<span class="params">first_terms, factors, n</span>):</span><br><span class="line"> series = {i: first_terms[i] <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="built_in">len</span>(first_terms))}</span><br><span class="line"> _f6(factors, n, series)</span><br><span class="line"> <span class="keyword">return</span> series[n]</span><br><span class="line"> </span><br><span class="line"><span class="keyword">def</span> <span class="title function_">_f6</span>(<span class="params">factors, n, series</span>):</span><br><span class="line"> <span class="keyword">if</span> n <span class="keyword">in</span> series:</span><br><span class="line"> <span class="keyword">return</span></span><br><span class="line"> x = <span class="number">0</span></span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">1</span>, <span class="built_in">len</span>(factors) + <span class="number">1</span>):</span><br><span class="line"> _f6(factors, n - i, series)</span><br><span class="line"> x += factors[-i] * series[n - i]</span><br><span class="line"> series[n] = x</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html"><h1 id="Exercise-1"><a href="#Exercise-1" class="headerlink" title="Exercise 1"></a>Exercise 1</h1><h3 id="what-is-yield-in-python"><a href=</summary>
<category term="Python" scheme="https://longsizhuo.github.io/tags/Python/"/>
<category term="Answer" scheme="https://longsizhuo.github.io/tags/Answer/"/>
<category term="9021" scheme="https://longsizhuo.github.io/tags/9021/"/>
<category term="Tutorial" scheme="https://longsizhuo.github.io/tags/Tutorial/"/>
</entry>
</feed>